一文带你玩透结构体和方法

  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...

你可能感兴趣的:(go)