结构体
- 如何给结构体创建
方法
?函数名前面e,g, 下面的(t T)叫做接收者,是一个特殊的参数
,下面的A和B均叫做方法
无法给内置类型创建方法,只能给自定义创建
- 接收者,拥有值接收者和指针接收者区别
值接收者
对传入的T类型的副本产生作用
指针接收者
对传入的T类型直接进行操作,具体理解看下面 - 指针可以直接操作
方法
,但是函数必须要传入对应类型的参数 - 普通函数 参数如果不是指针 也是值传递(意味着操作的是参数的拷贝)
func main() {
var t T
t = T{1, 2}
fmt.Println("初始化T: ", t)
t.A()
fmt.Println("执行A方法后:", t)
t.B()
fmt.Println("执行B方法后:", t)
ptr_t := &t
ptr_t.A()
ptr_t.B()
fmt.Println("指针可以直接执行 >>>方法<<<<")
}
func (t T) A() {
t.X = 10
}
func (t *T) B() {
t.X = 20
}
结果
初始化T: {1 2}
执行A方法后: {1 2}
执行B方法后: {20 2}
指针可以直接执行 >>>方法<<<<
接口
先看代码
type T struct {
Name string
}
type I interface {
Rename(name string)
}
func (t *T) Rename(new_name string) {
t.Name = new_name
fmt.Println("修改名字为:", t.Name)
}
func main() {
t := T{Name: "Bob"}
var interface_1 I = &t
interface_1.Rename("Jam")
fmt.Println(interface_1)
t.Rename("CCC")
fmt.Println(interface_1)
}
- 实现接口可以通过指针接收或者值接收者形式实现、如果是指针接收者实现,在进行接口赋值时需要取地址(
如何理解?是T类型的指针实现了Rename函数,而非T类型实现了。所以T类型的指针才是I接口的实现
) - 但是根据结构体 指针接收者情况,所以可以直接使用T类型调用Rename,
e.g. t.Rename("CCC")
定义空接口
var i interface{},i可以接收任何类型值,任何类型都拥有空实现。这玩意能当参数,e.g. 看下面
func main() {
Func_1(1)
Func_1("ABC")
Func_1(true)
Func_1(nil)
Func_1('c')
}
func Func_1(arg interface{}) {
fmt.Printf("传入类型为:%T, 值为:%v \n", arg, arg)
}
结果:
传入类型为:int, 值为:1
传入类型为:string, 值为:ABC
传入类型为:bool, 值为:true
传入类型为:<nil>, 值为:<nil>
传入类型为:int32, 值为:99
常用接口
- Stringer接口的String() string 用于类型的描述,类似C#的System.Object ToString()方法
- error接口的 Error() string
func (t *T) Error() string {
temp := fmt.Sprintf("我是%s,我也不知道,我有什么错", t.Name)
return temp
}
func get_error() error {
return &T{"Bob"}
}
func main() {
er := get_error()
fmt.Println(er)
}
结果:
我是Bob,我也不知道,我有什么错
类型断言
func main() {
var i interface{}
i = "XXX"
s, ok := i.(string)
if ok {
fmt.Println(s)
}
}
结果:
XXX