当前位置:网站首页>Go-接口的那些事
Go-接口的那些事
2022-08-09 09:27:00 【草明】
- 收者是 T
- 成员方法/属性的调用者可以是 T 和 *T
- 接口的动态类型可以是 T 和 *T
- 接收者是 *T
- 成员方法/属性的调用者可以是 T 和 *T
- 接口的动态类型可以只能是 *T
- 接口的动态类型是 nil, 接口不是nil
- 接口的动态类型是 nil, 不可以调用动态类型的属性, 单可以调用动态类型的方法(调用的过程中, 不能调用动态类型的属性)
上代码, 自己品
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self Dog) SetName(name string) {
self.name = name
}
func (self Dog) Name() string {
return self.name
}
func main() {
//接收者是 T
dog := &Dog{
"Max"}
// 成员方法/属性的调用者可以是 T 和 *T
fmt.Println((*dog).Name())
fmt.Println(dog.Name())
fmt.Println((*dog).name)
fmt.Println(dog.name)
// 接口的动态类型可以是 T 和 *T
var pet Pet = *dog
fmt.Println(pet.Name())
var pet2 Pet = dog
fmt.Println(pet2.Name())
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
self.name = name
}
func (self *Dog) Name() string {
return self.name
}
func main() {
//接收者是 *T
dog := &Dog{
"Max"}
// 成员方法调用者可以是 T 和 *T
fmt.Println((*dog).Name())
fmt.Println(dog.Name())
fmt.Println((*dog).name)
fmt.Println(dog.name)
// 接口的动态类型可以只能是 *T
// Error: Cannot use '*dog' (type Dog) as type Pet Type does not implement 'Pet' as 'Name' method has a pointer receiver
//var pet Pet = dog
var pet2 Pet = dog
fmt.Println(pet2.Name())
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self Dog) SetName(name string) {
self.name = name // 此处是副本, 无法改变外面的
}
func (self Dog) Name() string {
return self.name
}
func main() {
//接收者是 T
dog := &Dog{
"Max"}
(*dog).SetName("Bear")
fmt.Println("dog name:", (*dog).Name()) // Max
fmt.Println("dog name:", dog.Name()) // Max
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
var pet Pet = *dog
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("pet name:", pet.Name()) // Max
var pet2 Pet = dog
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("pet2 name:", pet2.Name()) // Max
// pet 包含的是 T 的副本, 所以 pet 的 name 没有改变
// pet2 包含的是 *T 的副本(指向的是同一个 T), 所以 pet2 的 name 改变了
dog.name="Bear"
fmt.Printf("dog: %v, name: %s\n", &dog, dog.Name()) // 0xc000124018, Bear
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc00010c250, Max
fmt.Printf("pet2: %v, name: %s\n", &pet2, pet2.Name()) // 0xc00010c290, Bear
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self Dog) SetName(name string) {
(&self).name = name // 此处是副本的指针, 无法改变外面的
}
func (self Dog) Name() string {
return self.name
}
func main() {
//接收者是 T
dog := &Dog{
"Max"}
(*dog).SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("dog name:", (*dog).Name()) // Max
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("dog name:", dog.name) // Max
var pet Pet = *dog
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("pet name:", pet.Name()) // Max
var pet2 Pet = dog
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Max
fmt.Println("pet name:", pet2.Name()) // Max
dog.name="Bear"
fmt.Printf("dog: %v, name: %s\n", dog, dog.Name()) // 0xc0000ac018, Bear
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc000096250, Max
fmt.Printf("pet2: %v, name: %s\n", &pet2, pet2.Name()) // 0xc000096290, Bear
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
self.name = name
}
func (self *Dog) Name() string {
return self.name
}
func main() {
//接收者是 *T
dog := &Dog{
"Max"}
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Bear
dog.SetName("Cooper")
fmt.Println("dog name:", (*dog).Name()) // Cooper
fmt.Println("dog name:", dog.Name()) // Cooper
var pet Pet = dog
dog.SetName("Milo")
fmt.Printf("dog: %v, name: %s\n", &dog, dog.Name()) // 0xc00000e028, Milo
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc000010270, Milo
dog.name = "Duke"
fmt.Printf("dog: %v, name: %s\n", &dog, dog.Name()) // 0xc00000e028, Duke
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc000010270, Duke
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
(*self).name = name
}
func (self *Dog) Name() string {
return self.name
}
func main() {
//接收者是 *T
dog := &Dog{
"Max"}
dog.SetName("Bear")
fmt.Println("dog name:", dog.Name()) // Bear
dog.SetName("Cooper")
fmt.Println("dog name:", (*dog).Name()) // Cooper
fmt.Println("dog name:", dog.Name()) // Cooper
var pet Pet = dog
dog.SetName("Milo")
fmt.Printf("dog: %v, name: %s\n", &dog, dog.Name()) // 0xc0000ac018, Milo
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc000096250, Milo
dog.name = "Duke"
fmt.Printf("dog: %v, name: %s\n", &dog, dog.Name()) // 0xc0000ac018, Duke
fmt.Printf("pet: %v, name: %s\n", &pet, pet.Name()) // 0xc000096250, Duke
}
package main
import "fmt"
type Pet interface {
Name() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
(*self).name = name
}
func (self *Dog) Name() string {
return self.name
}
func main() {
var dog *Dog
fmt.Printf("%v, %v\n", &dog, dog) // 0xc00000e028, <nil>
dog2 := dog
if dog2 == nil {
fmt.Printf("nil: %v, %v\n", &dog2, dog2) // nil: 0xc00000e038, <nil>
} else {
fmt.Printf("not nil: %v, %v\n", &dog2, dog2)
}
// 因为 Pet 是接口, 所以 pet 是 iface 的实例, 包装了 dog2 的副本, pet 不是 nil, 但是它被包装的动态值是 nil
var pet Pet = dog
if pet == nil {
fmt.Printf("nil: %v, %v\n", &pet, pet)
} else {
fmt.Printf("not nil: %v, %v\n", &pet, pet) // not nil: 0xc000010230, <nil>
}
}
package main
import "fmt"
type Pet interface {
Name() string
Category() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
(*self).name = name
}
func (self *Dog) Name() string {
return self.name
}
func (self *Dog) Category() string {
return "Dog"
}
func main() {
var dog *Dog
fmt.Printf("%v, %v\n", &dog, dog) // 0xc00000e028, <nil>
// dog 是 nil, 接口的实例 pet 不是 nil
// pet 可以调用动态类型 Dog 的成员方法, 但是成员方法不可以使用接收者的属性
var pet Pet = dog
fmt.Println(pet.Category()) // Dog
fmt.Println(pet.Name()) // panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x108b900]
}
package main
import "fmt"
type Pet interface {
Name() string
Category() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
(*self).name = name
}
func (self *Dog) Name() string {
return self.Category()
}
func (self *Dog) Category() string {
return "Dog"
}
func main() {
var dog *Dog
fmt.Printf("%v, %v\n", &dog, dog) // 0xc00000e028, <nil>
// dog 是 nil, 接口的实例 pet 不是 nil
// pet 可以调用动态类型 Dog 的成员方法, 但是成员方法不可以使用接收者的属性, 可以调用接收者的方法, 但是所有的调用链中, 不可以包含接收者的属性
var pet Pet = dog
fmt.Println(pet.Category()) // Dog
fmt.Println(pet.Name()) // Dog
}
package main
type Pet interface {
Name() string
Category() string
}
type Dog struct {
name string
}
func (self *Dog) SetName(name string) {
(*self).name = name
}
func (self *Dog) Name() string {
return self.name
}
func (self *Dog) Category() string {
return "Dog"
}
// 一个类型只实现了接口部分的方法, 只要不当作接口的动态类型使用, 程序不会出错
// 如果是故意为之, 可以忽略
// 如果是想实现接口的, 只是遗漏/名称错误, 可以使用以下小技巧验证是否实现了某个接口
// 验证是否实现了某个接口
var _ Pet = (*Dog)(nil)
边栏推荐
- 接口测试主要测试哪方面?需要哪些技能?要怎么学习?
- 学习双向链表的心得与总结
- TypeScript Brief (1)
- Redis high availability
- 软件测试的流程规范有哪些?具体要怎么做?
- 6.Map接口与实现类
- web测试之功能测试常用的方法有哪几种?有什么要点要注意?
- A Practical Guide to Building OWL Ontologies using Protege4 and CO-ODE Tools - Version 1.3 (7.4 Annotation Properties - Annotation Properties)
- TestNG使用教程详解
- Ontology Development Diary 03-Understanding Code
猜你喜欢
随机推荐
.ts 音频文件转换成 .mp3 文件
3.练习Thread
Another implementation of lateral view explode
div模拟textarea文本框,输入文字高度自适应,且实现字数统计和限制
Ontology development diary 04 - to try to understand some aspects of protege
单元测试是什么?怎么写?主要测试什么?
4.字符流
Ontology Development Diary 03-Understanding Code
全网最全的软件测试基础知识整理(新手入门必学)
3.List接口与实现类
Django实现对数据库数据增删改查(一)
Golang Protobuf 处理
有返回值的函数
第四讲 SVN
try catch 对性能影响
Ontology Development Diary 03 - When debugging is in progress
本体开发日记01-Jena配置环境变量
软件测试的流程规范有哪些?具体要怎么做?
Domestic Google earth, terrain analysis seconds kill with the map software
性能测试报告包括哪些内容?模板范文哪里找?看这里