GO结构体方法(一些实例)

目录

别名定义

                示例:变量别名定义

                示例:结构体别名定义

工厂模式

Tag原信息

                结构体与JSON序列化

                结构体标签(Tag)      

Golang匿名字段 :

方法

        示例:传统数据类型自定义方法,做数据类型转化。


别名定义

                示例:变量别名定义

package main
​
import "fmt”
​
type integer int
​
func main(){
    //类型别名定义
    var i integer=1000
​
    fmt.Printin(i)
​
    var j int = 100
​
    //但是属于不同类型,需要做强转
    j = int(i)
​
    fmt.Println(j)
}
运行结果

1000
1000

                示例:结构体别名定义

package main
​
import "fmt"
​
type student struct {
​
    Number int
)
    //结构体别名
type stu student
​
    func main(){
​
        var a Student
        a = Student{30}
​
        var b Stu
​
        b = Stu{300}
​
        //强转类型
​
        a = Student(b)
        fmt.Println(a)
}
运行结果

{300}

工厂模式

        创建构造体时初始化构造体,即对构造体属性变量赋初始值。在Go中没有构造函数,可以使用工厂模式来解决。

示例:

package main
​
import "fmt"
​
type student struct {
​
    Name string
​
    Age int
}
​
func main(){
​
    stu1 :=new(Student)
               
    stu2 := NewStudent("zhangsan",20)
​
    fmt.Println(stu1)
​
    fmt.Println(stu2)
}
//工厂模式
​
func NewStudent(name string,age int) *Student {
​
    return &student{
​
        Name: name,
​
        Age:age,
    }
}
运行结果

&{ 0}
&{zhangsan 20}

强调:

1: make用来创建map.slice、channel"

2: new用来创建值类型

Tag原信息

                结构体与JSON序列化

        跟其他语言进行对接交互时使用JSON格式,有些语言格式有规范大小写严格,为了使Go能和其他语言对接数据传输,故使用Tag原信息来解决。

        JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON键值对是用来保存JS对象的一种方式,键/值对组合中的键名写在前面并用双引号""包裹,使用冒号:分隔,然后紧接着值;多个键值之间使用英文,分隔。
        

示例

package main
​
import(
​
    "encoding/json"
    "fmt"
)
type Student struct {
    Name string
​
    Age int
    Score float32
}
​
func main() {
​
    var stu Student = Student{
​
        Name: "stu1",
​
        Age: 18,
        Score: 80,
}
//使用json格式返回字节数组
​
    data,err := json.Marshal(stu)
    if err != nil {
​
        fmt. Println("json encode stu failed,err:", err)
        return
    }
    fmt.Println(data)//字节数组形式输出
​
    fmt. Println(string(data)) //转换成字符串输出
}
​
运行结果

[123 34 78 97 109 101 34 58 34 115 116 117 49 34 44 34 65 103 101 34 58 49 56 125]
{"Name":"stu1","Age":18}
​

                结构体标签(Tag)      

        Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来。

        Tag在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下:

    `key1:"value1" key2:"value2"`

        结构体标签由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。键值对之间使用一个空格分隔。 注意事项: 为结构体编写Tag时,必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。例如不要在key和value之间添加空格。

示例:JSON格式字段名

package main
​
import (
    "encoding/json"
    "fmt"
)
​
type Student struct {
    //json打包时字段名
​
    Name  string  `json:"name"`
    Age   int     `json:"age"`
    Score float32 `json:"score"`
}
​
func main() {
​
    var stu Student = Student{
​
        Name: "stu1",
​
        Age:   18,
        Score: 80,
    }
    //使用json格式返回字节数组
    data, err := json.Marshal(stu)
    if err != nil {
​
        fmt.Println("json encode stu failed , err: ", err)
        return
    }
​
    fmt.Println(data)
​
    fmt.Println(string(data))
}
​
​
运行结果

[123 34 110 97 109 101 34 58 34 115 116 117 49 34 44 34 97 103 101 34 58 49 56 44 34 115 99 111 114 101 34 58 56 48 125]
{"name":"stu1","age":18,"score":80}

Golang匿名字段 :

        可以像字段成员那样访问匿名字段方法,编译器负责查找。

package main
​
import "fmt"
​
type User struct {
    id   int
    name string
}
​
type Manager struct {
    User
}
​
func (self *User) ToString() string { // receiver = &(Manager.User)
    return fmt.Sprintf("User: %p, %v", self, self)
}
​
func main() {
    m := Manager{User{1, "Tom"}}
    fmt.Printf("Manager: %p\n", &m)
    fmt.Println(m.ToString())
}
输出结果:

    Manager: 0xc42000a060
    User: 0xc42000a060, &{1 Tom}

        通过匿名字段,可获得和继承类似的复用能力。依据编译器查找次序,只需在外层定义同名方法,就可以实现 "override"。

package main
​
import "fmt"
​
type User struct {
    id   int
    name string
}
​
type Manager struct {
    User
    title string
}
​
func (self *User) ToString() string {
    return fmt.Sprintf("User: %p, %v", self, self)
}
​
func (self *Manager) ToString() string {
    return fmt.Sprintf("Manager: %p, %v", self, self)
}
​
func main() {
    m := Manager{User{1, "Tom"}, "Administrator"}
​
    fmt.Println(m.ToString())
​
    fmt.Println(m.User.ToString())
}
输出结果:

    Manager: 0xc420074180, &{{1 Tom} Administrator}
    User: 0xc420074180, &{1 Tom}

方法

Go中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct.

方法定义

func (recevier type) methodName(参数列表)(返回值列表){}
​
    参数和返回值可以省略
    
• 只能为当前包内命名类型定义方法。
• 参数 receiver 可任意命名。如方法中未曾使用 ,可省略参数名。
• 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接口或指针。 
• 不支持方法重载,receiver 只是参数签名的组成部分。
• 可用实例 value 或 pointer 调用全部方法,编译器自动转换。

        一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。

package main
​
import (
    "fmt"
)
​
//结构体
type User struct {
    Name  string
    Email string
}
​
//方法
func (u User) Notify() {
    fmt.Printf("%v : %v \n", u.Name, u.Email)
}
func main() {
    // 值类型调用方法
    u1 := User{"golang", "golang@golang.com"}
    u1.Notify()
    // 指针类型调用方法
    u2 := User{"go", "go@go.com"}
    u3 := &u2
    u3.Notify()
}
输出结果:

    golang : golang@golang.com 
    go : go@go.com

解释: 首先我们定义了一个叫做 User 的结构体类型,然后定义了一个该类型的方法叫做 Notify,该方法的接受者是一个 User 类型的值。要调用 Notify 方法我们需要一个 User 类型的值或者指针。

在这个例子中当我们使用指针时,Go 调整和解引用指针使得调用可以被执行。注意,当接受者不是一个指针时,该方法操作对应接受者的值的副本(意思就是即使你使用了指针调用函数,但是函数的接受者是值类型,所以函数内部操作还是对副本的操作,而不是指针操作。

我们修改 Notify 方法,让它的接受者使用指针类型:

package main
​
import (
    "fmt"
)
​
//结构体
type User struct {
    Name  string
    Email string
}
​
//方法
func (u *User) Notify() {
    fmt.Printf("%v : %v \n", u.Name, u.Email)
}
func main() {
    // 值类型调用方法
    u1 := User{"golang", "golang@golang.com"}
    u1.Notify()
    // 指针类型调用方法
    u2 := User{"go", "go@go.com"}
    u3 := &u2
    u3.Notify()
}
输出结果:

    golang : golang@golang.com 
    go : go@go.com

注意:当接受者是指针时,即使用值类型调用那么函数内部也是对指针的操作。

方法不过是一种特殊的函数,只需将其还原,就知道 receiver T 和 *T 的差别。

package main
​
import "fmt"
​
type Data struct {
    x int
}
​
func (self Data) ValueTest() { // func ValueTest(self Data);
    fmt.Printf("Value: %p\n", &self)
}
​
func (self *Data) PointerTest() { // func PointerTest(self *Data);
    fmt.Printf("Pointer: %p\n", self)
}
​
func main() {
    d := Data{}
    p := &d
    fmt.Printf("Data: %p\n", p)
​
    d.ValueTest()   // ValueTest(d)
    d.PointerTest() // PointerTest(&d)
​
    p.ValueTest()   // ValueTest(*p)
    p.PointerTest() // PointerTest(p)
}
输出:

    Data: 0xc42007c008
    Value: 0xc42007c018
    Pointer: 0xc42007c008
    Value: 0xc42007c020
    Pointer: 0xc42007c008

demo

package main
​
import "fmt"
​
type Car struct {
​
  Name  string
​
  Color string
​
}
​
type Bike struct {
​
  Car
​
  wheel float32
​
}
​
type Triat struct {
​
  Car
​
  weight int16
​
}
​
func (c Car) Run() {
​
  fmt.Println("运行中")
​
}
​
func main() {
​
  var bike Bike
​
  bike.Name = "九二"
​
  bike.Color = "red"
​
  bike.wheel = 2
​
  fmt.Println(bike)
​
  bike.Run()
​
  var t Triat
​
​
​
  t.Name = "AudiRs 7"
​
  t.Color = "black"
​
  t.weight = 10000
​
  fmt.Println(t)
​
  t.Run()
​
}
运行结果

{{九二 red} 2}
运行中
{{AudiRs 7 black} 10000}
运行中

        示例:传统数据类型自定义方法,做数据类型转化。

package main
​
import "fmt"
​
type integer int
//传统数据类型自定义方法
​
func (p integer) convert() string {
​
    return fmt.Sprintf("%d",p)
}
func main(){
​
    var i integer
    i = 100
​
    s := i.convert()
​
    fmt.Printf("类型:%T,值:%s\n", s,s)
}
运行结果

类型:string 值:100
值类型和引用类型

package main
​
import "fmt"
​
type integer int
​
//传统数据类型自定义方法
func (p integer) convert() string {
    return fmt.Sprintf("%d", p)
}
​
//使用指针数据同步修改
func (p *integer) set(b integer) {
    *p = b
}
func main() {
    var i integer = 100
    s := i.convert()
    fmt.Printf("类型:%T,值:%s\n", s, s)
    fmt.Printf("类型:%T,值: %d\n", i, i)
    i.set(200)
    fmt.Println(i)
}
​
运行结果

类型:string,值:100
类型:main.integer,值: 100
200

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小柏ぁ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值