当前位置 : 主页 > 编程语言 > 其它开发 >

Go语言学习——结构体、构造函数、方法和接收者、给自定义类型添加方法

来源:互联网 收集:自由互联 发布时间:2022-06-03
构造函数:返回一个结构体变量的函数 Go语言 面向接口编程 结构体是值类型,赋值的时候都是拷贝 package mainimport "fmt"// 构造函数type person struct {name stringage int}type dog struct {name string}/

构造函数:返回一个结构体变量的函数

Go语言 面向接口编程

结构体是值类型,赋值的时候都是拷贝

package main

import "fmt"

// 构造函数

type person struct {
	name string
	age int
}

type dog struct {
	name string
}

// 构造函数:约定成俗new开头
// 返回的是结构体还是结构体指针
// 当结构体比较大的时候尽量使用结构体指针,减少程序的内存开销
func newPerson(name string, age int) person{
	return person{
		name: name,
		age: age,
	}
}

func newDog(name string) dog {
	return dog{
		name: name,
	}
}

func main(){
	p1 := newPerson("林黛玉", 16)
	p2 := newPerson("贾宝玉", 18)
	fmt.Println(p1, p2)

	d1 := newDog("大黄")
	fmt.Println(d1) // {大黄}
}

方法和接收者

方法

package main

import "fmt"

// 方法

type dog struct {
	name string
}

// 构造函数
func newDog(name string) dog {
	return dog{
		name: name,
	}
}

// 方法是作用于特定类型的函数
// 接收者表示的是调用该方法的具体类型变量,多用类型名首字母小写表示
func (d dog)wang(){
	fmt.Println("汪汪汪...")
	fmt.Printf("%s:汪汪汪\n", d.name)
}

func main(){
	d1 := newDog("小白")
	d1.wang()
}

格式:

func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
    函数体
}

什么时候应该使用指针类型接收者

  1. 需要修改接收者中的值
  2. 接收者是拷贝代价比较大的大对象
  3. 保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。

    package main
    
    import (
    	"fmt"
    )
    
    // 方法
    
    // 标识符:变量 函数名 类型名 方法名
    // Go语言中如果标识符首字母是大写的,就表示外部包可见(暴露的 公有的)
    
    // Dog 这是一个狗的结构体
    // type Dog struct {
    type dog struct {
    	name string
    }
    
    type person struct {
    	name string
    	age int
    }
    
    // 构造函数
    func newDog(name string) dog {
    	return dog{
    		name: name,
    	}
    }
    
    func newPerson(name string, age int) person{
    	return person{
    		name: name,
    		age: age,
    	}
    }
    
    // 方法是作用于特定类型的函数
    // 接收者表示的是调用该方法的具体类型变量,多用类型名首字母小写表示
    func (d dog)wang(){
    	fmt.Println("汪汪汪...")
    	fmt.Printf("%s:汪汪汪\n", d.name)
    }
    
    // 使用值接收者:传拷贝进去
    func (p person) guonian(){
    	p.age ++
    }
    
    // 指针接收者:传内存地址进去
    func (p *person) zhenguonian(){
    	p.age++
    }
    
    func (p *person)dream(){
    	fmt.Println("改变世界改变自己")
    }
    
    func main(){
    	d1 := newDog("小白")
    	d1.wang()
    
    	p1 := newPerson("理想", 18)
    	fmt.Println(p1.age) // 18
    	p1.guonian()
    	fmt.Println(p1.age)  // 18
    	p1.zhenguonian()
    	fmt.Println(p1.age) // 19
    	p1.dream()
    }

给自定义类型添加方法

package main

import "fmt"

// 给自定义类型加方法
// 不能给别的包里面的类型添加方法,只能给自己包里的类型添加方法

type myInt int

func (m myInt)hello(){
	fmt.Println("我是一个Int")
}

func main(){
	m := myInt(100) // int8(10)
	// m := 10 // int
	m.hello()
}

问题

package main

import "fmt"

// 结构体问题

// myInt(100)是什么
type myInt int

func (m myInt)hello(){
	fmt.Println("我是一个Int")
}

type person struct {
	name string
	age int
}

func main(){
	// 声明一个int32类型的变量x,它的值是10
	// 方法1
	// var x int32
	// x = 10
	// 方法2
	// var x int32 = 10
	// var x = 10
	// 方法3
	// var x = int32(10)
	// 方法4
	// x := int32(10)
	// fmt.Println(x)

	// 声明一个myInt类型的变量m,它的值是100
	// 方法1:
	// var m myInt
	// m = 100
	// 方法2:
	// var m myInt = 100
	// 方法3:
	// var m = myInt(100)
	// 方法4:
	// m := myInt(100) // 强制类型转换
	// fmt.Println(m)

	// m := myInt(100) // int8(10)
	// // m := 10 // int
	// m.hello()

	// 问题2:结构体初始化
	
	// 方法1:
	var p person // 声明一个person类型的变量p
	p.name = "理想"
	p.age = 18
	fmt.Println(p)
	var p1 person
	p1.name = "奈莎"
	p1.age = 12
	fmt.Println(p1)
	// 方法2
	s1 := []int{1,2,3}
	m1 := map[string]int{
		"stu1": 100,
		"stu2": 88,
		"stu3": 99,
	}
	fmt.Println(s1, m1)
	// 键值对初始化
	var p2 = person{
		name: "仲尼",
		age: 15,
	}
	fmt.Println(p2)
	// 值列表初始化
	var p3 = person{
		"黛玉",
		18,
	}
	fmt.Println(p3)
}

// 问题3:为什么要有构造函数
func newPerson(name string, age int)person{
	// 别人调用我,我能给它一个person类型的变量
	// tmpP := person{
	return person{
		name: name,
		age: age,
	}
	// return tmpP
}

// func newPerson(name string, age int)*person{
// 	// 别人调用我,我能给它一个person类型的变量
// 	// tmpP := person{
// 	return &person{
// 		name: name,
// 		age: age,
// 	}
// 	// return tmpP
// }
上一篇:阿里算法大佬:Kaggle首战拿金牌总结!
下一篇:没有了
网友评论