2017-04-12 66 views
0

我想創建一個使用切片界面的函數。Go中的特定界面切片

例如我有一個接口ider,它包含一個ID() string函數。然後我有一個類型(Field),它實現了ider接口。現在我有不同的對象,其中有ider作爲參數片。

在我的功能裏面,我期待一分ider[]ider)。該功能應該由不同類型使用,這些類型正在實施ider

這很難描述。因此,這裏是一個完整的例子,它輸出以下錯誤:

cannot use myObj.Fields (type []*Field) as type []ider in argument to inSlice

type ider interface { 
    ID() string 
} 

type Field struct { 
    Name string 
} 

// Implements ider interface 
func (f *Field) ID() string { 
    return f.Name 
} 

type MyObject struct { 
    Fields []*Field 
} 

// uses slice of ider 
func inSlice(idSlice []ider, s string) bool { 
    for _, v := range idSlice { 
     if s == v.ID() { 
      return true 
     } 
    } 
    return false 
} 

func main() { 
    fields := []*Field{ 
     &Field{"Field1"}, 
    } 
    myObj := MyObject{ 
     Fields: fields, 
    } 
    fmt.Println(inSlice(myObj.Fields, "Field1")) 
} 

https://play.golang.org/p/p8PPH51vxP

我已經尋找答案,但我只是發現了空接口,而不是針對特定的人的解決方案。

+0

可以使用idler接口來創建「fields」變量,如下所示:fields:= [] ider {{Field1}},} {}}。它運行在你去遊樂場的鏈接。 – mgagnon

+4

[golang:slice of struct!=它實現的接口的切片?]的可能的副本(http://stackoverflow.com/questions/12994679/golang-slice-of-struct-slice-of-interface-it-implements) –

+0

@mgagnon是的工作。我剛剛編輯了這個問題,因爲我的問題嵌套在一個附加類型中。 – apxp

回答

1

正如人們可以在https://golang.org/ref/spec#Calls

Except for one special case, arguments must be single-valued expressions assignable to the parameter types of F and are evaluated before the function is called.

讀所以在上面的代碼myObj.Fields[]*Field是類型的需要被分配給[]ider的代碼編譯的。讓我們來檢查一下情況。正如人們可以在https://golang.org/ref/spec#Assignability

A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:

  • x's type is identical to T.
  • x's type V and T have identical underlying types and at least one of V or T is not a named type.
  • T is an interface type and x implements T.
  • x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type.
  • x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
  • x is an untyped constant representable by a value of type T.
  1. []*Field[]ider相同的閱讀? https://golang.org/ref/spec#Type_identity告訴我們

    Two slice types are identical if they have identical element types.

    那麼,*Fieldider相同? 上述人士告訴我們

    A named and an unnamed type are always different.

    因此,沒有,沒有,因爲*Field是無名和ider而得名。

  2. 基礎類型的[]*Field[]*Field是和下面的類型的[]ider[]ider,而這些都是不相同的,正如我們在1校驗所以這也是不適用的。請閱讀here https://golang.org/ref/spec#Types

  3. 不適用,因爲[] ider不是接口類型,而是片類型。讀到這裏https://golang.org/ref/spec#Slice_types

  4. 也不適用,因爲沒有使用

  5. 也是不適用的信道,因爲沒有零使用

  6. 也不適用,因爲沒有使用恆定的。

所以總結:[]*Field類型的值是不能分配給[]ider,因此我們不能與參數類型[]ider一個函數調用的參數位置 使用[]*Field類型的表達式。

+0

在去你通常會做'var asIder [] ider; for _,v:=範圍myObj.Fields {asIder = append(asIder,v)}; inSlice(asIder,「Field1」)'或者將函數中的轉換封裝起來。 – Krom