ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Go: 复合数据类型struct

2021-04-11 14:10:05  阅读:190  来源: 互联网

标签:struct Point int 数据类型 Go Circle main type


结构体

结构体是将零个或多个任意类型的命名变量组合在一起的聚合数据类型。每个变量都叫做结构体的成员。

type Employee struct {
    ID      int
    Name    string
    age     int
}

Employee就是一个结构体。

定义结构体时要注意

1.如果一个成员变量的首字母大写,则它是可导出的。

2.成员变量的顺序对于结构体的同一性很重要,顺序不同表示不同的结构体。

3.结构体中的成员变量类型不能是结构体本身,但可以是该结构体的指针类型

type Node struct {
    value   int
    next    *Node
    //这样是非法的
    //next  Node
}

4.结构体的零值由结构体成员的零值构成。

结构体变量的声明

type Point struct {
    X   int
    Y   int
}

// 方式一
p1 := Point{1, 2} // X=1 Y=2
// 方式二
p2 := Point{X: 3, Y: 4} // X=3 Y=4

// 如果某个成员变量没有指定,那么该成员变量的值为该类型零值
p3 := Point{Y:6} // X=0 Y=6

方式一和方式二不可以混用。并且不能通过方式一绕过不可导出变量无法在其他包中使用的规则

// p.go
package p
type T struct { a, b int }

// q.go
package q
import "p"
var _ = p.T{1, 2}  // 编译错误
var _ = p.T{a: 1, b: 2} // 编译错误

如果在函数中需要修改结构体变量的内容时,需要传递指针

type Point struct {
	X, Y int
}

func update(p Point, x int) { // 函数接收到的是实惨的一个副本
	p.X = x
}

func update2(p *Point, x int) {
	p.X = 2
}

func main() {
    p := Point{}
	update(p, 1)
	fmt.Println(p)  // {0 0}
	update2(&p, 2)
	fmt.Println(p)  // {2 2}
}

结构体的比较

必须所有的成员变量是可比较的,那这个结构体是可变比较

type Point struct {
	X, Y int
}

type Book struct {
	name     string
	chapters []string
}

func main() {
	p1 := Point{X: 1, Y: 2}
	p2 := Point{X: 1, Y: 2}
	p3 := Point{X: 1, Y: 3}
	fmt.Println(p1 == p2, p2 == p3)  // true false

	b1 := Book{name: "abc", chapters: []string{"1", "2"}}
	b2 := Book{name: "abc", chapters: []string{"1", "2"}}
	fmt.Print(b1 == b2) // 编译错误,无法比较,因为chapters是slice类型 不能比较 
}

结构体嵌套和匿名成员

结构体嵌套的目的是为了复用
Go允许我们定义不带名称的结构体成员(即匿名成员),这样可以快捷访问到匿名成员里的成员变量

type Point struct {
	X, Y int
}

type Circle struct {
	Point
	Radius int
}

type Wheel struct {
	Circle
	Spokes int
}

func main() {
	var w Wheel
	w.X = 8         // 等价于w.Circle.Point.X
	w.Y = 8
	w.Radius = 5    // 等价于w.Circle.Radius
	w.Spokes = 20

	fmt.Printf("%#v", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
}

外围的结构体Wheel不仅获得匿名成员Circle的内部成员变量,也会获得Circle的方法

type Point struct {
	X, Y int
}

func (p Point) Print() {
	fmt.Printf("%#v", p)
}

type Circle struct {
	Point
	Radius int
}

func (c Circle) Print() {
	fmt.Printf("%#v", c)
}


type Wheel struct {
	Circle
	Spokes int
}

// func (w Wheel) Print() {
// 	fmt.Printf("%#v", w)
// }

func main() {
	var w Wheel
	w.X = 8
	w.Y = 8
	w.Radius = 5
	w.Spokes = 20

	fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
	w.Print() // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
}

如果在Wheel上再加一个匿名命名成员Band, 它也有Print方法

type Band struct {
	Name string
}

func (b Band) Print() {
	fmt.Printf("%#v", b)
}

type Wheel struct {
	Circle
	Band
	Spokes int
}


func main() {
	var w Wheel
	w.X = 8
	w.Y = 8
	w.Radius = 5
	w.Spokes = 20

	fmt.Printf("%#v\n", w) // main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Band:main.Band{Name:""}, Spokes:20}
	w.Print() // 编译报错 
    w.Circle.Print()  // main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}
    w.Band.Print()  // main.Band{Name:""}
}

如果外围结构体WheelPrint方法,会直接调用该方法;如果没有,但其内部的多个匿名成员都有该方法,需要显示指定调用哪个匿名结构体的Print方法

标签:struct,Point,int,数据类型,Go,Circle,main,type
来源: https://www.cnblogs.com/Zioyi/p/14643633.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有