golang 方法

1.方法的定义:

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

1)func (p Person) test()表示P结构体有一方法,方法名为test

2)(p Person)体现test方法是和Person类型是绑定的

3)test方法只能通过Person类型的变量来调用,而不能直接调用,也不能使用其他类型变量来调用

复制代码
type Person struct {
    Name string
}

func (p Person) test() {
    fmt.Println("test()", p.Name)
}
func main() {
    var p Person
    p.Name = "Tom"
    p.test()
}
复制代码
2.方法的细节
1)结构体在方法的调用中是值拷贝
给Person结构体添加计算方法,可以接收参数n,计算从1+...+n的结果,并返回结果
复制代码
//给Person结构体添加计算方法,可以接收参数n,计算从1+...+n的结果,并返回结果
func (person Person) cal(n int) int {
    sum := 0
    for i := 1; i <= n; i++ {
        sum += i
    }
    return sum
}
func main() {
    var person Person
    person.Name = "Tom"
    n1 := person.cal(100)
    fmt.Println(n1)
}
复制代码

给出半径求面基

复制代码
type Circle struct {
    Radius float64
}

func (c Circle) area() float64 {
    return c.Radius * c.Radius * 3.14
}
func main() {
    var c Circle
    c.Radius = 4.0
    a1 := c.area()
    fmt.Println(a1)
}
复制代码
2)为了提供效率,通常跟结构体指针绑定
复制代码
//为了提供效率,通常跟结构体指针绑定
func (c *Circle) area2() float64 {
    //return (*c).Radius * (*c).Radius * 3.14 底层为了简单等价于下面
    return c.Radius * c.Radius * 3.14
}
func main() {
    var c Circle
    c.Radius = 4.0
    //a2 := (&c).area2() 底层为了简单等价于下面
    a2 := c.area2()
    fmt.Println(a2)
}
复制代码

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

复制代码
func (i integer) print() {
    i = 20
    fmt.Println("i=", i)
}
func (i *integer) print1() {
    *i = 20
    fmt.Println("i=", *i)
}
func main() {
    var i integer = 10
    i.print()
    fmt.Println(i)
    i.print1()
    fmt.Println(i)
}
复制代码

4)方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其他包访问。

5)如果一个类型实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出。

复制代码

//给*Student实现方法String()
type Student struct {
    Name string
    Age  int
}

func (stu *Student) String() string {
    str := fmt.Sprintf("Name=[%v],Age=[%v]\n", stu.Name, stu.Age)
    return str
}
func main() {
    stu := Student{
        "tom",
        20,
    }
    fmt.Println(stu)
  //如果实现了*Student 类型是String方法,就会自动调用
  fmt.Println(&stu) 
}
复制代码

3.方法和函数的区别

1)调用方式不一样

函数的调用方式: 函数名(实参列表)

方法的调用方式: 变量.方法名(实参列表)

2)对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然

3)对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以

总结:

1)不管调用形式如何,真正决定是值拷贝还是地址拷贝的是看这个方法是和哪个类型绑定的

2)如果是和值类型,比如(p Person),则是值拷贝,如果是和指针类型,比如(p *Person)则是地址拷贝。

复制代码
func (p Person) test03() {
    p.Name = "jack"
    fmt.Println("test03()", p.Name)
}
func main() {
    p1 := Person{"TOM"}
    p1.test03()
    fmt.Println(p1.Name)
    //从形式上看是地址拷贝,但是实际上仍然是值拷贝,因为在test03是(p Person)是值拷贝。编译器把(&p1).test03()底层改为p1.test03()而不会报错
    (&p1).test03()
    fmt.Println(p1.Name)
复制代码

 

posted @   潇潇暮鱼鱼  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2022-03-01 ecs健康检查问题
点击右上角即可分享
微信分享提示