英文:
Go Syntax and interface as parameter to function
问题
这段代码是一个方法的定义,它属于一个名为ContactRecord
的结构体的方法集合中。这个方法的名字是Less
,它接受一个interface{}
类型的参数other
,并返回一个bool
类型的值。
在Go语言中,interface{}
类型可以表示任意类型的值。在这个方法中,参数other
被声明为interface{}
类型,这意味着它可以接受任何类型的值作为参数。
在方法的实现中,other
参数被转换为*ContactRecord
类型,并通过.(*ContactRecord)
语法进行类型断言。然后,它调用rec.sortKey.Less()
方法,并将断言后的other
作为参数传递进去。
总的来说,这个方法的作用是比较rec
和other
两个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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论