var _ I = (*T)(nil)
在Go语言中,没有设计的" 实现 "声明.要求编译器通过尝试赋值来检查类型T是否实现接口I的唯一方法(是的,虚拟的:).注意,Go lang区分结构和指针上声明的方法,在赋值检查中使用正确的方法!
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
如何保证我的类型满足接口?
您可以要求编译器检查该类型是否T实现了接口,方法I是尝试使用 0 值T或指向 的指针T(视情况而定)。
我们可以用一个例子来说明这一点:
package main
type I interface{ M() }
type T struct{}
func (T) M() {}
//func (*T) M() {} //var _ I = T{}: T does not implement I (M method has pointer receiver)
// 如果T(或*T,相应地)没有实现I,错误将在编译时被捕获。请参阅接口实现中的非接口方法。
func main() {
//avoids allocation of memory
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
//allocation of memory
var _ I = &T{} // Verify that &T implements I.
var _ I = new(T) // Verify that new(T) implements I.
}
通常,如果您不知道某个值的类型,则检查该值是否实现了接口。如果已知,则检查由编译器自动完成。
*Go &T{}和new(T)和(T)(nil)区别
- (* T)(nil) 它返回nil指针或没有指针,但仍然为struct的所有字段分配内存。
- new(T)和& T {} 完全等价:分配一个零T并返回一个指向这个分配的内存的指针。唯一的区别是,& T {} 不适用于内置类型,如 int ;你只能做 new(int)。
package main
import (
"fmt"
)
type Struct struct {
Field int
}
func main() {
test1 := &Struct{}
test2 := new(Struct)
test3 := (*Struct)(nil)
fmt.Printf("%#v, %#v, %#v \n", test1, test2, test3) //&main.Struct{Field:0}, &main.Struct{Field:0}, (*main.Struct)(nil)
fmt.Printf("%T, %T, %T \n", test1, test2, test3) // *main.Struct, *main.Struct, *main.Struct
test1.Field = 1
fmt.Println(test1.Field) // 1
test2.Field = 2
fmt.Println(test2.Field) // 2
test3.Field = 3 // test3分配内存,返回一个nil指针,不能使用
// fmt.Println(test3.Field)
}
参考:https://qa.1r1g.com/sf/
https://blog.csdn.net/weixin_40580582/article/details/118686221?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-1-118686221-blog-129443153.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-1-118686221-blog-129443153.pc_relevant_default&utm_relevant_index=1