Go語言中的Struct結構體
一、Struct結構體
Go語言中沒有像C#、Java一樣的Class,只有Struct這樣的結構體。Go語言使用type關鍵字來定義一個類型。
如下:
type User struct {
Name string
Age int32
Sex int16
AvatarUrl string
}二、Struct的聲明以及初始化
初始化方法一:直接定義,通過變量名.成員名的方式賦值
//初始化方法1
var user1 User
user1.Name = "BigOrange"
user1.Age = 20
user1.Sex = 1
user1.AvatarUrl = "xxxxxxx"
fmt.Println("User1:",user1)初始化方法二:直接通過{}進行初始化,這點和C#不一樣,C#初始化的時候一般用new,例如 var user = new User{xxxxx,xxxxx,xxxx}
//初始化方法2
var user2 User = User{
Name:"BigBanana",
Age:23,
Sex:0,
AvatarUrl:"yyyyyyyyyyy",
}
fmt.Println("User2:",user2)
//初始化方法2簡化
user3 := User{
Name:"BigBanana",
Age:23,
Sex:0,
AvatarUrl:"yyyyyyyyyyy",
}
fmt.Println("User3:",user3)三、Struct的指針
Struct的指針比較簡單,就是通過&獲取地址,此外還可以用new來返回一個對象的指針
方式一
var user4 *User = &User{
Name:"BigPeach",
Age:22,
Sex:1,
AvatarUrl:"zzzzzzz",
}
fmt.Println("User4:",user4)
fmt.Println("User4:",*user4)方式二
user5 := new(User)
user5.Name="BigGrape"
user5.Age= 25
user5.Sex= 1
user5.AvatarUrl= "mmmmmmmmm"
fmt.Println("User5:",user5)
fmt.Println("User5:",*user5)上面第二種方式可能會有些疑問,user5不是一個指針類型嗎?怎么和上面的值類型一樣直接用【變量名.成員】 的方式進行賦值了呢? 不是應該 (*user5).Name 這樣嗎?沒有錯!
這是GO語言實現(xiàn)的一個語法糖,實際上GO語言會幫我轉換。
四、Struct成員的內(nèi)存布局以及實現(xiàn)構造函數(shù)
例如下面這樣的一段代碼
package main
import "fmt"
type AddressDemo struct {
addr1 int32
addr2 int32
addr3 int32
}
func main(){
addr := new(AddressDemo)
fmt.Println("add1地址:",&addr.addr1)
fmt.Println("add2地址:",&addr.addr2)
fmt.Println("add3地址:",&addr.addr3)
}結果:
add1地址: 0xc042060080
add2地址: 0xc042060084
add3地址: 0xc042060088
可以看出來,addr1、addr2、addr3都是int32,都是占用了4個字節(jié),他們的地址分配都是連續(xù)的。
For example: 下面這個User包,就實現(xiàn)了一個NewUser的方法,他就是構造函數(shù)
package User
type User struct {
Name string
Age int32
Sex int16
AvatarUrl string
}
func NewUser(name string , age int32,sex int16,avatarUrl string) *User{
user:=new(User)
user.Name = name
user.Age = age
user.Sex = sex
user.AvatarUrl = avatarUrl
return user
}五、Struct中的匿名字段和嵌套
可以像下面這樣聲明:后兩個字段沒有名字
type Class struct {
Name string
int
string
}使用的時候,對于匿名的字段,直接賦值就可以了
class1:=Class{
Name:"Class1",
int:123,
string:"sssssss",
}
fmt.Println("class1:",class1)結構體的嵌套
type User struct {
Name string
Age int32
Sex int16
AvatarUrl string
}
type Class struct {
Name string
}
type Student struct {
User User
Class Class
}使用:
func main() {
stu:=new(User.Student)
stu.Class = User.Class{
Name:"5-2",
}
stu.User = User.User {
Name:"BigBanana",
Sex:1,
Age:12,
AvatarUrl:"asdasdasd",
}
fmt.Println(stu)
}如果是匿名結構體嵌套呢?修改一下Student
type Student struct {
User User
Class
}使用在對Class這個成員進行賦值的時候,可以發(fā)現(xiàn),既可以使用
stu.Class = User.Class{
Name:"5-2",
}也可以使用Name直接賦值,順序就是現(xiàn)在當前的結構體找,找不到再從匿名結構體中查找,正好找到Class里面有Name
stu.Name = "5-2"
如果Class和User都是匿名結構嵌套,但是他們里面都有Name,當我們使用stu.Name的時候,那他訪問的是Class里的Name還是User里面的Name? 那么豈不是沖突了? 如何處理沖突?
當我試圖給stu.Name賦值的時候,編譯器報錯了,內(nèi)容如下,也就是它找不到應該給誰賦值。

這時候要解決這個沖突,必須指定是哪個匿名字段里面的Name
stu:=new(User.Student)
stu.User.Name = "123123"
stu.Class.Name = "5-2"
stu.User = User.User {
Name:"BigBanana",
Sex:1,
Age:12,
AvatarUrl:"asdasdasd",
}六、結構體內(nèi)字段的可見性
和包一樣,小寫的字段外部不可見,大寫的外部可見
七、結構體的Tag
tag是結構體的元信息,可以在運行的時候通過反射的機制讀出來。
怎么寫tag?
以`作為開頭和結尾,中間是key-value形式的字符串,每一個鍵值對以,作為分隔。例如
type User struct {
UserName string `json:"userName",db:"User_Name"`
Age int32 `json:"age"`
Sex int16 `json:"sex"`
AvatarUrl string `json:"avatarUrl",db:"Avatar_Url"`
}使用并運行:
func main() {
user := User.User {
UserName:"BigBanana",
Sex:1,
Age:12,
AvatarUrl:"asdasdasd",
}
fmt.Println(user)
data,_:=json.Marshal(user)
fmt.Println(string(data))
}結果:
{"userName":"BigBanana","age":12,"sex":1,"avatarUrl":"asdasdasd"}可以看到,如果打了這個tag,會顯示tag后面的標記名稱。
此外:如果字段名稱是小寫,那么json輸出的時候就不會有這個字段被打印了。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內(nèi)容請查看下面相關鏈接
相關文章
Go開發(fā)go-optioner工具實現(xiàn)輕松生成函數(shù)選項模式代碼
go-optioner?是一個在?Go?代碼中生成函數(shù)選項模式代碼的工具,可以根據(jù)給定的結構定義自動生成相應的選項代碼,下面就來聊聊go-optioner是如何使用的吧2023-07-07

