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