Struct是一个用户定义的类型,包含一系列的字段。它通常被作为一个整体组织相关的数据。相对java来说,就类似一个没有继承特性的贫血模型类。
定义struct
type User struct {
name string
age string
nationality string
}
初始化struct
初始化可以带字段名,可以不带字段名
func TestInit(t *testing.T) {
u1 := User{}
u2 := User{"Jack", 30, "Italy"}
u3 := User{
name: "Mark",
age: 30,
nationality: "China",
}
t.Log(u1) // { 0 }
t.Log(u2)
t.Log(u3)
}
匿名struct
func TestAnonymousStruct(t *testing.T) {
u1 := struct {
name string
nationality string
age int
}{
name: "Logan",
nationality: "China",
age: 35,
}
u2 := struct {
name string
nationality string
age int
}{
"Logan",
"China",
35,
}
if u1 != u2 {
t.Fail()
} else {
t.Log("u1 equals u2")
}
}
嵌套struct
func TestNestedStruct(t *testing.T) {
type FullName struct {
first string
last string
}
type User struct {
name FullName
nationality string
age int
}
p := User{
name: FullName{first: "Logan", last: "Wang"},
nationality: "French",
age: 34,
}
t.Log(p.name.first)
}
内嵌的结构体的字段可以被promoted
什么意思呢?就像上面的例子,p.name.first
可以变成p.first
,就像first直接就是User的字段一样。
func TestPromotedField(t *testing.T) {
// 内嵌的匿名结构体的字段会被promoted,
// 也就是说,它们可以在不引用内嵌的结构体的情况下访问
type FullName struct {
first string
last string
}
type User struct {
FullName
nationality string
age int
}
u := User{
FullName: FullName{
first: "Logan",
last: "Wang",
},
nationality: "French",
age: 34,
}
t.Log(u.first)
}
struct可以有functions field
func TestFunctionField(t *testing.T) {
type Age func() int
type User struct {
name string
nationality string
birthday time.Time
age Age // 函数字段
}
const TIME_LAYOUT = "2006-01-02 15:04:05"
birth, err := time.Parse(TIME_LAYOUT, "2000-01-01 00:00:00")
if err != nil {
t.Fail()
}
u := User{
name: "Good",
nationality: "Sweden",
birthday: birth,
age: func() int {
dur := time.Now().UTC().Sub(birth)
return int(dur.Hours() / 24 / 365)
},
}
ageInt := u.age()
t.Log(ageInt)
}
指针
可以通过&
操作符或者new
关键字创建指向结构体的指针。
func TestStructPoint(t *testing.T) {
u := User{"Jack", 30, "Italy"}
// pointer to struct
pointer_u := &u
(*pointer_u).age = 40
pointer_u.name = "New Name"
t.Log(u)
// use keyword new to create a pointer to struct
u2 := new(User)
u2.name = "Name2"
u2.age = 20
t.Log(u2)
}
// 使用构造函数
func TestWithConstruct(t *testing.T) {
u := newUser("Richard Roe", "Singapore", 44)
t.Log(u)
}
golang的结构体实际是个值类型
当将一个结构体赋值给一个变量的时候,实际上是分配了一个新的结构体,而不是分配了一个指针。比较两个结构体的时候,会逐层比较值,而不是引用。
func TestAssign(t *testing.T) {
u := User{"Jack", 30, "Italy"}
u2 := u
u2.age = 40
t.Log(u.age) // 30
t.Log(u2.age) // 40
}
func TestEqual(t *testing.T) {
type FullName struct {
first string
last string
}
type User struct {
FullName
nationality string
age int
}
u := User{
FullName: FullName{
first: "Logan",
last: "Wang",
},
nationality: "French",
age: 34,
}
u2 := User{
FullName: FullName{
first: "Logan",
last: "Wang",
},
nationality: "French",
age: 34,
}
if u == u2 {
t.Log("u == u2") // 会走到这里
} else {
t.Log("u != u2")
}
}
Be First to Comment