zoukankan      html  css  js  c++  java
  • Go:方法

    一、基本介绍

    在某些情况下,我们需要定义方法。比如 Person 结构体,除了有一些字段外(姓名、年龄...),还可以有一些行为动作(吃、唱歌...),这就需要用方法才能实现。

    Go中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是 struct 有。

    示例:

    type Person struct {
    	Name string
    }
    
    // 给Person类型绑定一个方法
    func (person Person) Eat() {
    	fmt.Printf("%s正在吃东西...", person.Name)
    }
    
    func main() {
    	person := Person{"pd"}
    	person.Eat() // 调用方法
    }
    

    对上面代码总结:

    1. Eat 方法和 Person 类型绑定;
    2. Eat 方法只能通过 Person 类型的(变量 / 实例 / 对象)来调用,而不能直接调用,也不能使用其他类型的实例来调用;
    3. func (person Person) Eat() {},person表示哪个Person的实例调用,可以理解为 java 中的 this,python 中的 self;
    4. 方法的参数、返回值与函数一样。

    二、方法的引用传递与值传递

    结构体是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝的传递方式。如果想在方法中,修改结构体字段的值,可以通过结构体指针的方式来处理。

    type Person struct {
    	Name string
    	Age int
    }
    
    func (p *Person) Change() {
    	/*
    	因为 p 是指针,所以标准的访问字段的方式是 (*p).Name,但写成
    	p.Name 也是可以的,因为编译器在底层会帮我们处理,方便程序员
    	使用。
    	同理,在下面的 main 函数中,本因 (&p).Change() 这样调用方法,
    	但写成 p.Change() 也是可以的。
    	 */
    	p.Name = "乔治"
    	p.Age = 20
    }
    
    func (p Person) Change1() {
    	p.Name = "诺手"
    	p.Age = 22
    }
    
    func main() {
    	p := Person{"佩奇", 10}
    	fmt.Println(p.Name, p.Age) // 佩奇 10
    	p.Change()
    	fmt.Println(p.Name, p.Age) // 乔治 20
    
    	p1 := Person{"德玛", 11}
    	p1.Change1()
    	fmt.Println(p1.Name, p1.Age) // 德玛 11
    	(&p1).Change1() // 同理,编译器会优化,因为 Change1() 中的Person不是一个指针
    	fmt.Println(p1.Name, p1.Age) // 德玛 11
    }
    

    结论:不管结构体实例是 p.Change() 还是 (&p).Change() 的形式调用方法,都是由方法中 p 对应的结构体是 *Person 还是 Person 决定的!!!,*Person就是引用传递,Person就是值传递。

  • 相关阅读:
    NJUPT_Wrj 个人训练实录
    图片保存本地,上传阿里云,保存该图片 在阿里云的 路径 到 本地数据库
    微信所有国家列表
    YII load()
    ab命令压力测试
    fatal: Could not read from remote repository
    JS获取URL中参数值的4种方法
    yii 生成 模型
    php子类是否自动调用父类构造函数
    自己实现一个简化版的SpringMVC框架
  • 原文地址:https://www.cnblogs.com/believepd/p/10934208.html
Copyright © 2011-2022 走看看