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

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 = "992424875@qq.com"
    fmt.Println(user)

    //初始化方式2
    user1 := User{"chavis", "1qaz#EDC", "847575@qq.com"}
    fmt.Println(user1)

    //初始化方式3
    user2 := User{username: "root", password: "abc@9089", mail: "root@11.com"}
    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种方式:变量定义、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: "1qaz@WSX", mail: "996298929@qq.com"}
    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)
}
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
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)
}
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
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
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语言是通过首字母的大小写来控制访问权限。无论是方法,变量,常量或是自定义的变量类型,如果首字母大写,则可以被外部包访问,反之则不可以。而结构体中的字段名,如果首字母小写的话,则该字段无法被外部包访问和解析。

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"}
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}

Original: https://www.cnblogs.com/ttropsstack/p/16749639.html
Author: 不背锅运维
Title: 一文带你玩透结构体和方法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582282/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球