题外话
有时候一直在纠结
学技术的意义到底是什么
我不认为我学的这些东西能让我做一辈子
20年前可能学个jq学个php
就可以跟着公司一路水涨船高
如今人均几十个技术库几个几个框架的学
最后又赚不了几个逼钱
起步源码级面试提问
学习到底有什么意义呢
原文
https://www.golinuxcloud.com/golang-anonymous-structs/
Golang 匿名结构定义及语法
在之前的文章,我们提到了golang的结构,其中我们简要介绍了匿名结构,现在给你一个简介的概念,匿名结构类型是不使用名字定义的结构,go允许你定义一个匿名字段:结构字段没有自身的名字,只有其类型声明
一个结构不具有名字将其成为匿名结构,因此,我们无法在代码的其他部分应用该结构,我们可以使用匿名结构定义临时的,短暂存在的接哦古
例如创建一个匿名结构
variable_name := struct {
// fields
}{field_values}
如何创建匿名结构
下方代码展示了如何在go创建一个匿名结构
package main
import "fmt"
func main() {
// create anon struct
person := struct {
name, nationality string
age int
score float64
}{
name: "Anna_Hurry",
nationality: "England",
age: 21,
score: 9.5,
}
// print anon struct
fmt.Println(person)
}
在这里例子,我们创建了一个匿名结构并立即创建一个结构的实例,代码应该打印出结构的数据
$ go run main.go
{Anna_Hurry England 21 9.5}
如何使用匿名结构在不同类型之间进行比较结构
结构完全由可比较的类型组成是可以进行比较的,但是结构拥有slice切片或map字段是不可以进行比较的,不同于python或ruby,在go没有任何方法可以复写相等函数为不可比较的结构使==或!=正常工作,当然,你可以写你自己的函数来比较结构。
在Go中允许执行类型转换在一个结构类型和另一个结构类型中,但是必须两个结构的字段的命名,顺序,和类型完全一致,让我们看看这个问题
这里我们有一个结构
type firstPerson struct {
name string
age int
}
我们可以使用类型转换将firstPerson转换为secondPerson,但是我们不可以使用==去比较firstPerson和secondPerson的实例,因为他们是完全不同的类型
type secondPerson struct {
name string
age int
}
我们不能使用转换将firstPerson转换为thirdPerson,因为字段是不同的顺序
type thirdPerson struct {
age int
name string
}
我们不能使用转换将firstPerson转换为fourthPerson,因为字段名字不匹配
type fourthPerson struct {
firstName string
age int
}
最终,我们不能转换将firstPerson转换为fifthPerson,因为他有额外的字段
type fifthPerson struct {
name string
age int
favoriteColor string
}
匿名结构在这里多出一个小转折:如果两个结构正在被比较和其中至少有一个是匿名类型,如果两个结构的字段,顺序,类型都完全一致,你可以在不进行类型转换的情况下进行比较,你也可以在具名类型和匿名类型之间做相互复制
package main
import (
"fmt"
)
type firstPerson struct {
name string
age int
}
func main() {
f := firstPerson{
name: "Bob",
age: 50,
}
var g struct {
name string
age int
}
// compiles -- can use = and == between identical named and anonymous structs
g = f
fmt.Println(f == g)
}
输出
$ go run main.go
true
推荐使用匿名结构而不是普通结构的例子
这里列出推荐的四个用例
全局组合
模板数据
表格测试
嵌入锁
全局组合
我们使用匿名结构将所有的配置变量收集到结构中,所以我们不需要再次引用该匿名结构
var config struct {
Username string
Password string
APIKey string
OAuthConfig oauth.Config
}
模板数据
一个匿名结构可以当作模板数据
data := struct {
Title string
Users []*User
}{
title,
users,
}
表格测试
下方代码演示了如何使用匿名结构去创建表格测试
var testData = []struct {
name string
age int
score float64
}{
{"a A x", 12, 5.5},
{"some_text=some_value", 10, 9.3},
{"a", 12, 8.2},
{"ab", 20, 6.7},
}
var testData = []struct {
name string
age int
score float64
}{
{"a A x", 12, 5.5},
{"some_text=some_value", 10, 9.3},
{"a", 12, 8.2},
{"ab", 20, 6.7},
}
//do some test here
嵌入锁
让互斥体靠近他要保护的数据是一种非常好的做法,如果有必要防止字段发生并发访问,将互斥体作为字段添加到结构中是非常方便的,它为人所知并在很小的程度上使用,但它也很方便它可以,可以将互斥体嵌入到结构中,并且可以调用Lock和Unlock,就好像是结构自身的一部分,看起来像这样
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++
hits.Unlock()
概括
匿名结构就像普通结构一样,但是没有定义名称,因此不能在其他地方引用,匿名结构的语法很简单,我们可以很容易的创建一个匿名结构,在某些情况下,如对全局变量进行组合,创建测试数据表,我们可以使用匿名而不是常规结构
参考
https://go.dev/talks/2012/10things.slide#3
https://pkg.go.dev/sync#Mutex