码迷,mamicode.com
首页 > 其他好文 > 详细

<12>Golang基础进阶——结构体

时间:2020-04-29 14:34:30      阅读:43      评论:0      收藏:0      [点我收藏+]

标签:err   ada   point   duration   退出   字段   lan   col   UNC   

Golang基础进阶——结构体

结构体(struct)

定义结构体

type 类型名 struct {
	字段1 字段1 类型
	字段2 字段2 类型
}

示例:

func main() {
	var s1 = Student{1, "zs", ‘f‘, 18, "sh"}
	fmt.Println(s1)

	var s2 = Student{id: 2, age: 25}
	fmt.Println(s2)

	var s3 Student
	s3.id = 3
	s3.age = 26
	fmt.Println(s3)

	s4 := &Student{4, "zs", ‘f‘, 18, "sh"}
	fmt.Println(s4)
	fmt.Println((*s4).id)
	fmt.Println(s4.id)
}

指针类型的结构体

type Player struct {
	Name        string
	HealthPoint int
	MagicPoint  int
}

func main (){
	tank := new(Player)
	fmt.Println(tank) // &{ 0 0}
	tank.Name = "Canon"
	(*tank).HealthPoint = 300
}

提示: Go 语言中,访问结构体指针的成员交量时可以继 使用 "."。这是因为 Go语言为了方便开发者访问结构体指针的成员变量,使用了语法糖技术,将ins.Name 形式转换为 (*ins).Name

值和指针作为参数

type Student struct {
	id   int
	name string
}

func temStudent(tmp Student) {
	tmp.id = 200
	fmt.Println(tmp)
}

func temStudent2(tmp *Student) {
	tmp.id = 300
	fmt.Println(tmp)
}
func main() {
	var s = Student{1, "zs"}
	temStudent(s)
	fmt.Println(s)

	temStudent2(&s)
	fmt.Println(s)
}

结构体内存结构

一个结构体,会占用一段连续的内存空间

type Student struct {
	A int32
	B int32
	C int32
	D int32
}
func main(){
	var s Student
	fmt.Printf("A addr: %p\n", &s)
	fmt.Printf("A addr: %p\n", &s.A)
	fmt.Printf("B addr: %p\n", &s.B)
	fmt.Printf("C addr: %p\n", &s.C)
	fmt.Printf("D addr: %p\n", &s.D)
}

构造函数

type User struct {
	id   int
	name string
	age  int
}

func NewUser(id int, name string, age int) *User {
	user := &User{
		id:   id,
		name: name,
		age:  age,
	}
	return user
}
func main() {
	user := NewUser(1, "wsl", 18)
	fmt.Println(user)
}

匿名字段

 go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段

type Person struct {
	name string
	sex  string
	age  int
}
type Student struct {
	Person
	id   int
	addr string
}

func main() {
	s1 := Student{Person{"zs", "fa", 20}, 1, "bj"}
	fmt.Println(s1)

	s2 := Student{Person: Person{"zs", "fa", 20}}
	fmt.Println(s2)

	s3 := Student{Person: Person{name: "zs"}}
	fmt.Println(s3)
}

同名字段的情况

type Person struct {
	name string
	sex  string
	age  int
}

type Student struct {
	Person
	id   int
	addr string
	name string
}

func main() {
	var s Student
	s.name = "z"
	fmt.Println(s) // {{  0} 0  z}

	s.Person.name = "ww"
	fmt.Println(s) // {{ww  0} 0  z}
}

指针类型匿名字段 

type Person struct {
	name string
	sex  string
	age  int
}

type Student struct {
	*Person
	id int
}

func main() {
	s1 := Student{&Person{"z", "m", 18}, 1}
	fmt.Println(s1) // {0xc00006a300 1}
}

内置类型和自定义类型

type Person struct {
	name string
	sex  string
	age  int
}
type mystr string
type Student struct {
	Person
	int
	mystr
}

func main() {
	s1 := Student{Person{"zs", "m", 18}, 1, "bj"}
	fmt.Println(s1)
}

 方法

 格式:

func (接收参数名 接收类型) 方法名(参数列表)(返回值)

基础类型作为接收者

type MyInt int

func Add(a, b MyInt) MyInt {
	return a + b
}

func (a MyInt) Add(b MyInt) MyInt {
	return a + b
}

func main() {
	var a MyInt = 1
	var b MyInt = 2

	fmt.Println(Add(a, b))
	fmt.Println(a.Add(b))
}

结构体作为接收者

type Person struct {
	name string
	sex  string
	age  int
}

func (p Person) PrintInfo() {
	fmt.Println(p.name, p.sex, p.age)
}
func main() {
	p := Person{"zs", "m", 18}
	p.PrintInfo()
}

值语义和引用语义

type Person struct {
	name string
	sex  string
	age  int
}

func (p *Person) SetInfoPointer() {
	(*p).name = "zs"
	p.sex = "fe"
	p.age = 20
}
func (p Person) SetInfoValue() {
	p.name = "ls"
	p.sex = "m"
	p.age = 20
}
func main() {
	p1 := Person{"ww", "male", 18}
	fmt.Println(p1) // {ww male 18}
	p1.SetInfoPointer()
	fmt.Println(p1) // {zs fe 20}
	p1.SetInfoValue()
	fmt.Println(p1) //{zs fe 20}
}

方法的继承

type Person struct {
	name string
	sex  string
	age  int
}

func (p *Person) PrintInfo(){
	fmt.Println(p.name,p.sex,p.age)
}
type Student struct {
	Person
	id int
	addr string
}
func main (){
	p := Person{"zs","m", 20}
	p.PrintInfo() // zs m 20

	s := Student{id:2,addr:"bj"}
	s.PrintInfo() //  0
}

方法的重写

type Person struct {
	name string
	sex  string
	age  int
}

func (p *Person) PrintInfo() {
	fmt.Println(p.name, p.sex, p.age)
}

type Student struct {
	Person
	id   int
	addr string
}

func (s *Student) PrintInfo() {
	fmt.Println("student:", s.name, s.sex, s.age)
}
func main() {
	p := Person{"zs", "m", 18}
	p.PrintInfo() // zs m 18

	s := Student{Person{"l", "m", 30}, 2, "b"}
	s.PrintInfo()
	// 还能调用父类方法
	s.Person.PrintInfo()
}

方法的实际运用

http包中的类型方法

func main() {
	client := &http.Client{}

	// 创建一个http请求
	req, err := http.NewRequest("POST", "http://www.163.com/", strings.NewReader("key=value"))

	// 发现错误就打印并退出
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
		return
	}

	// 为标头添加信息
	req.Header.Add("User-Agent", "myClient")

	// 开始请求
	resp, err := client.Do(req)

	// 处理请求的错误
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
		return
	}

	data, err := ioutil.ReadAll(resp.Body)
	fmt.Println(string(data))

	defer resp.Body.Close()

}

 在本例子使用的 req.Header 类型为 http.Header 就是典型的自定义类型,并且拥有自己的方法。 http.Header 部分定义如下:

type Header map[string][]string

func (h Header) Add(key, value string) {
	textproto.MIMEHeader(h).Add(key, value)
}

func (h Header) Get(key string) string {
	return textproto.MIMEHeader(h).Get(key)
}

Header 实际是一个以字符串为键、字符串切片为值的映射。Add() Header 的方法,map 是一个引用类型,因此即便使用(h Header)的费指针接收器,也可以修改map的值。

time 包中的类型方法

func main() {
	fmt.Println(time.Second.String())
}

 time Second一个常量,下面代码的加粗部分就是 time.Second 定义:

const (
	Nanosecond  Duration = 1
	Microsecond          = 1000 * Nanosecond
	Millisecond          = 1000 * Microsecond
	Second               = 1000 * Millisecond
	Minute               = 60 * Second
	Hour                 = 60 * Minute
)

Second 的类型为 Duration ,而 Duration 实际是 int64 的类型,定义如下:

type Duration int64

// 它拥有一个 String 的方法,部分定义如下:

func (d Duration) String() string {

	... ...

	return string(buf[w:])
}

Duration.String 可以将 Duration 值转为字符串。

 

<12>Golang基础进阶——结构体

标签:err   ada   point   duration   退出   字段   lan   col   UNC   

原文地址:https://www.cnblogs.com/Wshile/p/12801848.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!