posts - 134,comments - 0,views - 66631

1、结构体声明

1
2
3
4
type 结构体名称 struct{
    field type
    field type
}

举例:

1
2
3
4
5
type Dog struct {
    Name  string
    Age   int
    Color string
}

  

2、结构体使用

2.1 直接声明

1
var dog Dog

2.2 {}

1
2
3
4
5
6
7
8
9
10
type Dog struct {
    Name  string
    Age   int
    Color string
}
 
func main() {
    dog := Dog{"来福", 3, "白色"}
    fmt.Printf("dog=%v\n", dog)
}

2.3 new()  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Dog struct {
    Name  string
    Age   int
    Color string
}
 
func main() {
    dog := new(Dog)
    // dog是一个指针,因此标准的给字段赋值应该是(*dog).Name = "来福" (*dog).Age = 3 (*dog).Color = "白色"
    // go设计者为了程序员使用方便,底层会对dog.Name = "来福"进行处理,会给dog加上取值运算(*dog).Name = "来福"
    dog.Name = "来福"  // 等价于(*dog).Name = "来福"
    dog.Age = 3      // 等价于(*dog).Age = 3
    dog.Color = "白色" // 等价于(*dog).Color = "白色"
    fmt.Printf("dog=%v\n", *dog)
}

2.4 &

1
2
3
4
5
6
7
8
9
10
type Dog struct {
    Name  string
    Age   int
    Color string
}
 
func main() {
    dog := &Dog{"来福", 3, "白色"}
    fmt.Printf("dog=%v\n", *dog)
}

2.5 创建struct实例指定字段值 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Person struct {
    Name string
    Age  int
}
 
func main() {
    person := Person{
    Name: "Tom",
    Age:  18,
    }
 
    personPor := &Person{
    Name: "Jack",
    Age:  20,
    }
    fmt.Println("person=", person)
    fmt.Println("personPor=", *personPor)
} 

第三种方式和第四种方式返回的是结构体指针,结构体指针访问字段的标准方式应该是:(*结构体指针).字段名,比如(*dog).Name = "来福"

 

3、方法的声明

1
2
3
4
func (recevier type) methodName(参数列表)(返回值列表){
    方法体
    return 返回值
}

参数列表,表示方法输入

recevier type:表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型

recevier type:可以是结构体,也可以说是自定义类型。

recevier就是type类型的一个变量(实例)。

参数列表表示方法的输入

返回值列表,表示返回的值,可以是多个。

方法主体,表示为了实现某一功能代码块

return语句不是必须的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type Dog struct {
    Name  string
    Age   int
    Color string
}
 
// 给Dog类型绑定一个方法
func (d Dog) Eat(food string) {
    fmt.Printf("%v正在吃%v\n", d.Name, food)
}
 
func main() {
    d := Dog{
    Name:  "小花",
    Age:   3,
    Color: "花色",
    }
    // 调用方法
    d.Eat("骨头")
}

  

4、函数和方法的区别

调用方式不一样

函数的调用方式:函数名(实参列表)

方法的调用方式:变量.方法名(实参列表)

b. 对于普通函数,接收者是值类型时,不能将指针类型的数据直接传递

c. 对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type Person struct {
    Name string
    Age  int
}
 
func (p Person) test() {
    p.Name = "Merry"
}
 
func (p *Person) test01() {
    p.Name = "Jack"
}
 
func main() {
    person := Person{
    Name: "Tom",
    Age:  18,
    }
    person.test()
    fmt.Println("name=", person.Name)
    (&person).test() // 从形式上是传入地址,但本质任然是值拷贝
    fmt.Println("name=", person.Name)
    person.test01() // 等价于(&person).test01() 从形式上是传入值类型,但本质任然是地址拷贝
    fmt.Println("name=", person.Name)
    (&person).test01()
    fmt.Println("name=", person.Name)
}

输出:

1
2
3
4
name= Tom
name= Tom
name= Jack
name= Jack

不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和那个类型绑定的

如果是和值类绑定型,比如: (p Person) test(),则是值拷贝

如果是和地址类型绑定,比如:func (p *Person) test01(),则是地址拷贝

posted on   smile学子  阅读(105)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示