Go语法和接口作为函数的参数

huangapple go评论87阅读模式
英文:

Go Syntax and interface as parameter to function

问题

这段代码是一个方法的定义,它属于一个名为ContactRecord的结构体的方法集合中。这个方法的名字是Less,它接受一个interface{}类型的参数other,并返回一个bool类型的值。

在Go语言中,interface{}类型可以表示任意类型的值。在这个方法中,参数other被声明为interface{}类型,这意味着它可以接受任何类型的值作为参数。

在方法的实现中,other参数被转换为*ContactRecord类型,并通过.(*ContactRecord)语法进行类型断言。然后,它调用rec.sortKey.Less()方法,并将断言后的other作为参数传递进去。

总的来说,这个方法的作用是比较recother两个ContactRecord对象的排序键(sortKey),并返回比较结果的布尔值。

英文:

I am new to Go programming language and recently encountered the following code:

func (rec *ContactRecord) Less(other interface{}) bool {
  return rec.sortKey.Less(other.(*ContactRecord).sortKey);
}

However, I do not understand the meaning behind the function signature. It accepts an interface as a parameter. Could you please explain me how this works ? Thanks

答案1

得分: 53

Go语言使用接口来实现类型的泛化。所以,如果你想要一个接受特定接口的函数,你可以这样写:

func MyFunction(t SomeInterface) {...}

任何满足SomeInterface接口的类型都可以传递给MyFunction函数。

现在,SomeInterface可以定义如下:

type SomeInterface interface {
    SomeFunction()
}

要满足SomeInterface接口,实现它的类型必须实现SomeFunction()方法。

然而,如果你需要一个空接口(interface{}),则对象不需要实现任何方法就可以传递给函数:

func MyFunction(t interface{}) { ... }

上面的函数将接受任何类型作为参数(因为所有类型都实现了空接口)。

获取类型信息

现在你可以接受任何可能的类型,问题是如何获取之前传入的实际类型。空接口不提供任何方法,因此你无法在该值上调用任何东西。

为此,你需要使用类型断言:让运行时检查值Y中是否存在类型X,并在确实存在时将其转换为该类型。

示例:

func MyFunction(t interface{}) {
    v, ok := t.(SomeConcreteType)
    // ...
}

在这个示例中,输入参数t被断言为SomeConcreteType类型。如果t实际上是SomeConcreteType类型,v将持有该类型的实例,并且ok将为true。否则,ok将为false。详细信息请参阅类型断言的规范

英文:

Go uses interfaces for generalization of types. So if you want a function that takes a specific interface
you write

func MyFunction(t SomeInterface) {...}

Every type that satisfies SomeInterface can be passed to MyFunction.

Now, SomeInterface can look like this:

type SomeInterface interface {
    SomeFunction()
}

To satisfy SomeInterface, the type implementing it must implement SomeFunction().

If you, however, require an empty interface (interface{}) the object does not need to
implement any method to be passed to the function:

func MyFunction(t interface{}) { ... }

This function above will take every type as all types implement the empty interface.

Getting the type back

Now that you can have every possible type, the question is how to get the type back that
was actually put in before. The empty interface does not provide any methods, thus you
can't call anything on such a value.

For this you need type assertions: let the runtime check whether there is type X in value Y and
convert it to that type if so.

Example:

func MyFunction(t interface{}) {
    v, ok := t.(SomeConcreteType)
    // ...
}

In this example the input parameter t is asserted to be of type SomeConcreteType. If t
is in fact of type SomeConcreteType, v will hold the instance of that type and ok will
be true. Otherwise, ok will be false. See the spec on type assertions for details.

答案2

得分: 6

一个 interface 变量可以保存任何提供了与接口声明中签名相符的方法的类型的值。由于 interface{} 没有指定任何方法,这样的变量可以存储任何类型的值。

然后,该方法使用类型断言来检查 other 是否实际上是一个 *ContactRecord 值(否则会引发 panic)。

你可能会问为什么该方法没有声明为接受 *ContactRecord 参数。最有可能的原因是 *ContactRecord 类型实现了某个具有该签名的接口的 Less 方法。

英文:

An interface variable can hold values of any type that provides methods with the signatures from the interface declaration. Since interface{} doesn't specify any methods, such a variable can store values of any type.

The method then goes on to use a type assertion to check that other is actually a *ContactRecord value (it will panic otherwise).

You might then ask why the method isn't declared as taking a *ContactRecord argument then. The most likely reason is so that the *ContactRecord type implements some interface with a Less method with that signature.

huangapple
  • 本文由 发表于 2013年12月2日 00:48:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/20314604.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定