golang接口的使用:给实现类中属性赋值

yanglikai · · 3716 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

  1. 使用接口给实现类的变量赋值,例一错误;例二正确。
  2. &与*的不同用法,前者是取地址,后者是引用
  • 指针,或者说pointer是一串指向某个内存地址的字符串,所谓指向是指这串字符串的内容是内存地址的值
  • &表示取地址,比如有一个变量a那么&a就是变量a在内存中的地址;对于go,指针也是有类型的,比如如果a是一个string那么&a是一个string的指针类型:&string
  • 对于b := &a这句代码:a,b是两个不同的变量,a是string类型,b是&string类型;打印b,会发现它是一串内存地址,而非a的值;所以为了拿到a的值,有个操作*,用来取出指针对应内存地址里存的值,所以当打印*b,会发现跟a一模一样

 

例一:

package main

import (
     "fmt"
)

//声明一个接口
type IUser interface {
     GetName() string
     SetName(name string)
}

//声明一个User的结构去实现接口
type User struct {
     Name string
}

func (a User) GetName() string {
     return a.Name
}

func (a User) SetName(name string) {
     a.Name = name
}

func main() {
     var a IUser                   //声明a的类型是IUser类型
     a = User{"李磊"}               //给接口变量赋值
     fmt.Println(a.GetName())      //输出:李磊
     a.SetName("韩梅梅")
     fmt.Println(a.GetName())      //输出:李磊,这里实际想输出的是"韩梅梅"
}

 

例二:

package main

import (
     "fmt"
)

//声明一个接口
type IUser interface {
     GetName() string
     SetName(name string)
}

//声明一个User的结构去实现接口
type User struct {
     Name string
}

func (a User) GetName() string {
     return a.Name
}
//要改变对象的值必须用指针
func (b *User) SetName(name string) {
     b.Name = name
}

func main() {
     var a IUser                   //声明a的类型是IUser类型
     a = &User{"李磊"}              //a是指针了
     fmt.Println(a.GetName())      //输出:李磊
     a.SetName("韩梅梅")             
     fmt.Println(a.GetName())      //输出:韩梅梅


     b := &a
//     fmt.Println(b.GetName())  //这一步会报错:b.GetName undefined (type *IUser is pointer to interface, not interface)
     
     c := *b                       //相当于c=a
     c.SetName("小明")
     fmt.Println(c.GetName())      //输出:小明
     
     fmt.Println(a == c)           //true   
     fmt.Println(&a == &c)         //false
             
     fmt.Println(&a)               //变量a的内存地址
     fmt.Println(&b)               //变量b的内存地址
     fmt.Println(&c)               //变量c的内存地址
     fmt.Println(*b)               //解引用,输出b存储的数据(就是c)  输出:&{小明}
     //fmt.Println(*a)             //编译错误:invalid indirect of a (type IUser)
     
     x := &User{"李磊"}  
     fmt.Println(*x)               //{李磊}
     fmt.Println(x)                //&{李磊}
}

 


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3716 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传