Go语言学习杂记

本文介绍了Go语言中的格式化输出,包括%v、%+v和%#v等符号的用法。接着讨论了函数与方法的区别,特别是在接收者为值类型和指针类型时的不同。通过示例展示了如何定义和使用方法,以及何时选择值类型或指针类型作为方法接收者。此外,还探讨了方法继承的概念,并通过实例演示了如何实现。最后,文章通过JSON序列化展示了方法在实际应用中的价值。
摘要由CSDN通过智能技术生成

1、Go语言中的一些格式化输出符号

%v —— 只输出所有的值
%+v —— 先输出字段类型,再输出该字段的值
%#v —— 先输出结构体名字值,再输出结构体(字段类型+字段的值)

更多格式化输出符见:https://wenku.baidu.com/view/6393f769862458fb770bf78a6529647d2728343f.html

2、Go语言中方法和函数的区别

go语言中函数与方法的区别:对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递;对于方法,接收者为值类型时,可以直接用指针类型的变量调用方法。

3、Go Method

3.1 go方法的定义

Go的方法是在函数前面加一个接受者,这样编译器就知道这个方法属于哪个类型的了。以下是为一个类型定义一个方法的过程

img

示例:

package main
 
import (
    "fmt"
)
 
type Student struct { //定义了一个类型叫 Student。
    Name string
    Age  int
}
 
//定义了一个值类型为Student的GetName方法
func (stu Student) GetName() string { //为 Student 类型定义了一个方法叫 GetName
    return stu.Name
}
//定义了一个指针类型为Student的 SetName方法
func (stu Student) SetName(name string) { //为 Student 类型定义了一个方法叫 SetName,调用时需要传入一个参数
    stu.Name = name
}
 
func (stu *Student) Setname(name string) {
    stu.Name = name
}
func main() {
    //定义了一个类型为Student的变量
    //定义一个变量类型为Student,然后并赋值
    var s01 Student
    s01 = Student{
        Name: "s01",
        Age:  18,
    }
    name := s01.GetName()
    fmt.Printf("name=%s\n", name)
 
    s01.SetName("s02") //这里的s01就是,定义方法func (stu *Student) Setname(name string) 里面的stu,Stu就是s01的拷贝
    name = s01.GetName()
    fmt.Printf("name = %s\n", name)
 
    //(&s01).Setname("s02") 正规写法,下面的写法是GO帮助我们做了取地址的动作
    s01.Setname("s03")
    name = s01.GetName()
    fmt.Printf("name = %s\n", name)
}

*函数和方法的区别,函数不属于任何类型,方法属于特定的类型

*什么时候用值类型或指针类型做为方法的接受者?

1)需要修改接受者中的值的时候

2)接受者是大对象的时候,副本拷贝代价比较大

3)一般来说,通常使用指针类型作为同接受者,就可以了。

示例:

package main
 
import (
    "fmt"
    "time"
)
 
type User struct {
    s1 [10000000]int64
    s2 [10000000]int64
    s3 [10000000]int64
    s4 [10000000]int64
}
//func (u User) Set() {  换成值类型
func (u *User) Set() {
    for i := 0; i < len(u.s1); i++ {
        u.s1[i] = 1
        u.s2[i] = 1
        u.s3[i] = 1
        u.s4[i] = 1
    }
}
 
func main() {
    //var u *User = new(User)  //初始化指针
    var u *User = &User{  //初始化指针
    }
 
    start := time.Now().UnixNano()
    u.Set()
    end := time.Now().UnixNano()
 
    fmt.Printf("cost:%d ns\n", (end - start)/1000)
     
}

运行结果,运行速度提升近一倍

bogon:struct_copy jianglinguo$ ./struct_copy
cost:408596 ns
bogon:struct_copy jianglinguo$ go build
bogon:struct_copy jianglinguo$ ./struct_copy
cost:181123 ns

3.2 方法的继承
package main
 
import (
    "fmt"
)
 
type Animal struct {
    Name string
    Age int
}
 
func (a * Animal) SetName(name string) {
    a.Name = name
}
 
func (a *Animal) SetAge(age int) {
    a.Age = age
}
 
func (a * Animal) PrintHandle() {
    fmt.Printf("a.name = %s a.age = %d\n", a.Name, a.Age)
}
 
type Bird struct {
    //Animal
    //Animal *Animal  字段如果不指定名字默认使用Animal
    *Animal  //*Animal这个是指针要初始化一下,字段如果不指定名字默认使用Animal
}
 
func (b *Bird) Fly() {
    fmt.Printf("name %s is fly\n", b.Name)
}
 
func main() {
    var b *Bird = &Bird{
        Animal: &Animal{}, //初始化Animal
    }
    b.SetName("bird") //bird继承了Animal所以,b就有Animal的方法
    b.SetAge(13) //bird继承了Animal所以,b就有Animal的方法
    b.Fly()   //这个 Fly是bird的方法
}

JSON序列化

package main
 
import (
    "fmt"
    "encoding/json"
)
 
type Animal struct {
    Name string
    Age int
}
 
func (a * Animal) SetName(name string) {
    a.Name = name
}
 
func (a *Animal) SetAge(age int) {
    a.Age = age
}
 
func (a * Animal) PrintHandle() {
    fmt.Printf("a.name = %s a.age = %d\n", a.Name, a.Age)
}
 
type Bird struct {
    //Animal
    //Animal *Animal  字段如果不指定名字默认使用Animal
    *Animal  //*Animal这个是指针要初始化一下,字段如果不指定名字默认使用Animal
}
 
type Dog struct {
    *Animal
}
 
func (b *Bird) Fly() {
    fmt.Printf("name %s is fly\n", b.Name)
}
 
func main() {
    var b *Bird = &Bird{
        Animal: &Animal{}, //初始化Animal
    }
    b.SetName("bird") //bird继承了Animal类型所以,b就有Animal的方法
    b.SetAge(13) //bird继承了Animal类型所以,b就有Animal的方法
    b.Fly()   //这个 Fly是bird的方法
 
    data, err := json.Marshal(b)   //josn序列化
    fmt.Printf("marshal result:%s   err:%v\n", string(data), err)
 
    var c Bird
    err = json.Unmarshal(data, &c)  //json序列化
    fmt.Printf("c:%#v, err:%v\n", c.Animal, err)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值