惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
T
Tor Project blog
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
小众软件
小众软件
G
GRAHAM CLULEY
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
S
Schneier on Security
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
E
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
S
Securelist
Martin Fowler
Martin Fowler
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog

博客园 - 自然洒脱

MiniMax 权益码 Token Plan 套餐 9 折优惠 go语言context包 go语言通道 go语言GMP模型 go语言mongodb操作 go语言gorm的CRUD go语言gorm go语言mysql驱动 go语言log相关 go语言包管理 go语言时间相关 go语言序列化和反序列化 go语言的"面向对象" go语言结构体排序 go语言异常处理 go语言接口 go语言结构体(二) go语言递归函数及defer go语言函数作用域及匿名函数
go语言结构体(一)
自然洒脱 · 2023-07-03 · via 博客园 - 自然洒脱

结构体

Go语言的结构体有点像面向对象语言中的“类”,但不完全是,Go语言也没打算真正实现面向对象范式。

定义

使用type定义结构体,可以把结构体看做类型使用。必须指定结构体的字段(属性)名称和类型。

type User struct {
 id         int
 name, addr string // 多个字段类型相同可以合写
 score      float32
}

User不过是个标识符,是一个指代罢了 真正的类型定义是struct {} 的部分

初始化

type User struct {
 id         int
 name, addr string
 score float32
}
// 1 var声明,非常常用
var u1 User // 这种方式声明结构体变量很方便,所有字段都是零值
fmt.Println(u1)
fmt.Printf("%+v\n", u1) // 加上字段打印
fmt.Printf("%#v\n", u1) // 加上更多信息打印
// 2 字面量初始化,推荐
u2 := User{} // 字段为零值
fmt.Printf("%#v\n", u2)
// 3 字面量初始化,field: value为字段赋值
u3 := User{id: 100}
fmt.Printf("%+v\n", u3)
u4 := User{
 id: 102, score: 95.8,
 addr: "Nanjing", name: "Tom",
} // 名称对应无所谓顺序
u5 := User{103, "John", "Beijing", 98.5} // 无字段名称必须按照顺序给出全部字段值
fmt.Printf("%+v\n", u4)
fmt.Printf("%+v\n", u5)

initial

 可见性

Go包的顶层代码中,首字母大写的标识符,跨package包可见(导出),否则只能本包内可见

导出的结构体,package内外皆可见,同时,导出的结构体中的成员(属性、方法)要在包外也可见,则也需首字母大写

 查询和修改

可以使用字段名称访问和修改

 成员方法

利用下面形式为结构体组合方法,这是很方便自由地扩展方式。

type User struct {
 id         int
 name, addr string
 score      float32
}
// u称为receiver
// 等价于 func (User) string
func (u User) getName() string {
 return u.name
}
func main() {
 u1 := User{103, "John", "Beijing", 98.5}
 fmt.Println(u1.getName())
}

非引用类型

结构体是非引用类型,和数组一样,使用的是值拷贝。传参或返回值如果使用结构体实例,将产生很多副本。如果避免过多副本,可使用指针。

 
func test(p *Point) *Point {
    p.x = 20
    p.y = 30
    return p
}

type Point struct {
    x, y int
}

func main {
    p0 := Point{1, 2}
    fmt.Printf("%+v %[1]T %p\n", p0, &p0)
    p1 := p0 // 值拷贝类型
    fmt.Printf("%+v %[1]T %p\n", p1, &p1)
    p2 := &p0 // 引用指针来赋值,引用类型
    fmt.Printf("%+v %[1]T %p\n", p2, p2)
    p3 := test(p2)
    fmt.Printf("%+v %[1]T %p\n", p2, p2)
    fmt.Printf("%+v %[1]T %p\n", p3, p3)
    p3.x = 100 // 通过指针修改字段的值
    fmt.Printf("%+v %[1]T %p\n", p2, p2)
    fmt.Printf("%+v %[1]T %p\n", p3, p3)
    p4 := new(User) // 用new来生成一个新的零值实例
    fmt.Printf("%+v %[1]T %p\n", p4, p4)
}