【Golang】七、基础篇 --- 方法

一、方法定义

  1. 什么是方法?

    方法是作用于自定义数据类型上的,只可以由该数据类型声明的变量调用!
    定义:func (type type) funcName(行参列表) (返回列表) { }
    调用:变量.函数名(实参列表)

  2. 案例1:自定义结构体绑定的方法

    type Utils struct {
    	M int
    	N int
    }
    func (util Utils) PrintJX() (area int) {
    	for i := 0; i < util.M; i++ {
    		for i := 0; i < util.N; i++ {
    			fmt.Print("*")
    		}
    		fmt.Println()
    	}
    	area = util.M * util.N
    	return
    }
    
    func main() {
    	// 调用
    	util := Utils{1,2}
    	util.PrintJX()
    }
    
  3. 案例2:自定义数据类型绑定的方法
    自定义结构体中可以绑定方法,相同,自定义的数据类型也可以绑定一样的方法

    type nilstring string
    func (str nilstring) isNil() {
    	if str == "" {
    		fmt.Println(nil)
    	} else {
    		fmt.Println("not nil")
    	}
    }
    func main(){
    	var str nilstring
    	str.isNil()
    }
    

二、方法中的变量传递

1、结构体变量传值

结构体变量传递指针类型变量还是值类型变量,取决于方法定义接收的变量的类型,而不是传递的结构体变量的类型。

例子如下:

type Person struct {
	Name string `json:"name"`
	Age int `json:"age"`
}
// 接收指针类型的结构体变量
func (p *Person) ToString() string {
	str, _ := json.Marshal(p)
	return string(str)
}
// 接收值类型的结构体变量
func (p Person) ToString02() string {
	str, _ := json.Marshal(p)
	return string(str)
}
func main(){
	person := other.Person{"张三", 20}
	// 传递的person是指针类型
	person.ToString()
	(&person).ToString()

	// 传递的是值类型
	person.ToString02()
	(&person).ToString02()
}

如上所示,可以清除的看出,结构体变量传递的是值还是指针,取决于方法定义是指定的类型!!!

2、String()方法

直接输出调用结构体变量,会自动寻找自己类型下,是否有String()方法,如果有直接调用String()方法,没有则按照默认结构体输出!

// 结构体String()方法
func (p *Person) String() string {
	str, _ := json.Marshal(p)
	return string(str)
}

func main(){
	person := other.Person{"张三", 20}
	// 直接输出person此时会默认调用String()方法!!!
	// 类型必须和String()绑定变量的类型一致!!!
	fmt.Println(&person)
}

三、工厂模式的引入

场景:现在一个结构体是私有类型(首字母小写),但是我在别的包下想访问这个结构的数据,想获取结构体中某个字段的值,还想修改字段的值?该怎么做?


这时候工厂模式就派上了用场了

直接上案例:

  1. 创建fact.go
    type fact struct {
    	name string
    	age int
    }
    
    // 该函数用于构造一个结构体,并且返回该结构体的地址
    // 因为结构体是私有的,这里必须返回指针,否则无法使用该内部方法
    func NewFact(name string, age int) *fact01 {
    	return &fact01{name, age}
    }
    
    func (f fact) GetName() string {
    	return f.name
    	// return (*f).name
    }
    
    func (f *fact) SetName(name string) {
    	f.name = name
    	// 底层会做优化 =》(*f).name = name
    }
    
  2. 调用main.go
    package main
    
    import (
    	"fmt"
    	other "go_code/package10/other"
    )
    func main(){
    	fact := other.NewFact("zhangsna", 20)
    	fmt.Println(*fact)
    	fact.SetName("李四")
    	fmt.Println(fact.GetName())
    }
    

四、方法和函数的区别

  1. 调用方式不一样
    函数: 函数名(实参列表)
    方法: 变量.函数名(实参列表)

  2. 参数传递不一样
    函数: 接收参数类型必须一致,不能将指针类型数据直接传递(接收类型为指针,传参必须为地址),反之亦然。
    方法: 变量传递是值传递还是引用传递,取决于,方法定义的变量类型,例如:

    type struct struct {
    }
    func (struct *struct) test1()  {
    }
    func (struct struct) test2()  {
    }
    func main(){
    	// 引用传递
    	struct.test1()
    	// 引用传递
    	(&struct).test1()
    	
    	// 值传递
    	struct.test2()
    	// 值传递
    	(&struct).test2()
    }
    
  3. 可以粗糙理解为,函数是类方法,方法是实例方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小鱼小鱼啊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值