-
构造体的根本定义和应用
package main import ("fmt") // 定义构造体类型 User type User struct { username string "用户名" password string "明码" mail string "邮箱" } func main() { // 初始化形式 1 var user User user.username = "ttr" user.password = "abc123" user.mail = "[email protected]" fmt.Println(user) // 初始化形式 2 user1 := User{"chavis", "1qaz#EDC", "[email protected]"} fmt.Println(user1) // 初始化形式 3 user2 := User{username: "root", password: "[email protected]", mail: "[email protected]"} fmt.Println(user2) }
-
构造体嵌套
package main import "fmt" type Device struct { ip string user string pwd string loginType string ` 登录类型 ` } type Idc struct { device Device num int addr string } func main() { idc := Idc{device: Device{ip: "10.1.1.1", user: "root", pwd: "1qaz#EDC", loginType: "ssh"}, num: 907745, addr: "GZ", } fmt.Println(idc) }
输入:
{{10.1.1.1 root 1qaz#EDC ssh} 907745 GZ}
-
构造体实例化的 3 种形式
构造体定义完后是没有分配内存的,须要实例话之后才能够应用构造体。实例化有 3 种形式:变量定义、new、& 符号。
package main import "fmt" type Host struct { user string pwd string } func main() { // 变量定义的形式实例化构造体 var h Host h.user = "root" h.pwd = "1qaz#EDC" fmt.Println(h) // new 的形式实例化构造体 var h1 = new(Host) h1.user = "admin" h1.pwd = "2345#EDC" fmt.Println(h1) // & 符号定义的形式实例化构造体 var h2 = &Host{} h2.user = "ttr" h2.pwd = "98768#EDC" fmt.Println(h2) }
-
带标签的构造体,标签用于对字段进行阐明
package main import ("fmt") type User struct { username string "用户名" //"用户名" 是标签 password string "明码" mail string "邮箱" } func main() {user := User{username: "ttr", password: "[email protected]", mail: "[email protected]"} fmt.Println(user) }
-
匿名构造体
匿名构造体不必类型名称,不必应用 type 关键字定义。
package main import "fmt" func main() { // 根本构造 user := struct {}{} fmt.Println(user) // 定义和初始化 user1 := struct { name string age int }{ "tantianran", 18, } fmt.Println(user1) fmt.Println(user1.name) fmt.Println(user1.age) }
-
给构造体 User 增加办法 show(),该办法输入一个 hello
package main import ("fmt") type User struct { name string age int } func (User) show() {fmt.Println("hello") } func main() {u := User{name: "ttr", age: 17} u.show()}
-
给构造体增加办法,并将曾经初始化好的值能够在办法内拿到
package main import ("fmt") type User struct { name string age int } func (u User) show() {fmt.Println(u.name, u.age) } func main() {u := User{name: "ttr", age: 17} // 初始化并实例化 u.show() // 调用办法}
输入:
ttr 17
-
给构造体增加办法,并将曾经初始化好的值能够在办法内进行批改,留神这里是 *User,也就是指针类型
package main import ("fmt") type User struct { name string age int } func (u *User) chage() { u.name = "chavis" u.age = 30 } func main() {u := User{name: "ttr", age: 17} // 初始化和实例化 fmt.Println(u.name, u.age) // 批改前 u.chage() // 调用 chage 办法批改曾经初始化好的值 fmt.Println(u.name, u.age) // 批改后 }
输入:
ttr 17 chavis 30
如果不是指针类型,在办法内是无奈批改内部曾经初始化好的构造体的值,看上面成果
package main import "fmt" type User struct { name string age int } func (u User) chage() { u.name = "chavis" u.age = 30 } func main() {u := User{name: "ttr", age: 17} u.chage() fmt.Println(u) }
输入:
{ttr 17}
看下面的成果能够晓得没有被批改胜利,因为是值传递,而如果是指针的话,就是间接指向了曾经初始化了值且实例化完并赋给变量 u 所在的那块内存地址。
-
在上一个栗子的根底上做革新,使其有返回值,且返回值类型为指针类型
package main import ("fmt") type User struct { name string age int } func (u *User) chage() *User { u.name = "chavis" u.age = 30 return u } func main() {u := User{name: "ttr", age: 17} a := u.chage() fmt.Println(*a) }
输入:
{chavis 30}
-
在一个一般的函数内批改内部构造体的值
package main import "fmt" type User struct { name string age int } func chage(data *User) { data.name = "tantianran" data.age = 30 } func main() {u := &User{name: "ttr", age: 17} chage(u) fmt.Println(*u) // 也能够这样 u1 := User{name: "ttr", age: 17} chage(&u1) fmt.Println(u1) }
-
任意的类型也都是能够增加办法的,比方给 int 类型增加一个办法
package main import "fmt" type MyInt int func (x MyInt) check() bool { if x > 100 {return true} else {return false} } func main() {a := MyInt(56) ret := a.check() fmt.Println(ret) }
输入:
false
-
在上一个栗子的根底上,做一个加法,案例 1
package main import "fmt" type MyInt int func (x MyInt) add(y MyInt) MyInt {return x + y} func main() {a := MyInt(56) ret := a.add(54) fmt.Println(ret) }
输入:
110
-
构造体转成 json
package main import ( "encoding/json" "fmt" ) type Host struct { Hostname string Ip string } func main() { h := Host{ Hostname: "web01", Ip: "10.1.1.23", } if jsonStr, err := json.Marshal(h); err != nil {fmt.Println(err) } else {fmt.Println(string(jsonStr)) } }
输入:
{"Hostname":"web01","Ip":"10.1.1.23"}
留神:构造体的字段首写字母要大写,否则 json 包无奈读取到字段,进而转换失败(报错),Go 语言是通过首字母的大小写来管制拜访权限。无论是办法,变量,常量或是自定义的变量类型,如果首字母大写,则能够被内部包拜访,反之则不能够。而构造体中的字段名,如果首字母小写的话,则该字段无奈被内部包拜访和解析。
-
刚说到构造体的字段首写字母要大写,如果想转换成 json 后首字母是小写,能够减少标签来做到,看上面代码
package main import ( "encoding/json" "fmt" ) type Host struct { Hostname string `json:"hostname"` // 标签加在这里 Ip string `json:"ip"` // 标签加在这里 } func main() { h := Host{ Hostname: "web01", Ip: "10.1.1.23", } if jsonStr, err := json.Marshal(h); err != nil {fmt.Println(err) } else {fmt.Println(string(jsonStr)) } }
输入:
{"hostname":"web01","ip":"10.1.1.23"}
-
将 json 解析回构造体
package main import ( "encoding/json" "fmt" ) type Host struct { Hostname string Ip string } func main() {jsonData := `{"hostname":"web01","ip":"10.1.1.23"}` var h Host if err := json.Unmarshal([]byte(jsonData), &h); err != nil {fmt.Println("Error =", err) return } fmt.Println(h.Hostname) fmt.Println(h.Ip) fmt.Println(h) }
输入:
web01 10.1.1.23 {web01 10.1.1.23}
本文装载于:https://mp.weixin.qq.com/s/g6…