乐趣区

关于go:一文带你玩透结构体和方法

  1. 构造体的根本定义和应用

    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)
    }
  2. 构造体嵌套

    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 种形式

    构造体定义完后是没有分配内存的,须要实例话之后才能够应用构造体。实例化有 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)
    }
  4. 带标签的构造体,标签用于对字段进行阐明

    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)
    }
  5. 匿名构造体

    匿名构造体不必类型名称,不必应用 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)
    }
  6. 给构造体 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()}
  7. 给构造体增加办法,并将曾经初始化好的值能够在办法内拿到

    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
  8. 给构造体增加办法,并将曾经初始化好的值能够在办法内进行批改,留神这里是 *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 所在的那块内存地址。

  9. 在上一个栗子的根底上做革新,使其有返回值,且返回值类型为指针类型

    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}
  10. 在一个一般的函数内批改内部构造体的值

    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)
    }
  11. 任意的类型也都是能够增加办法的,比方给 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
  12. 在上一个栗子的根底上,做一个加法,案例 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
  13. 构造体转成 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 语言是通过首字母的大小写来管制拜访权限。无论是办法,变量,常量或是自定义的变量类型,如果首字母大写,则能够被内部包拜访,反之则不能够。而构造体中的字段名,如果首字母小写的话,则该字段无奈被内部包拜访和解析。

  14. 刚说到构造体的字段首写字母要大写,如果想转换成 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"}
  15. 将 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…

退出移动版