Go---方法

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

方法的声明

type A struct {
   Num int
}

func (a A)  test() {
fmt.Println(a .Num)

}

1) func (a A) test(){ } 表示A结构体有一方法,方法名为test
2) (a A)体现test方法是和A类型绑定的

for example

//自定义结构体

type A struct {

    Num int

}

//给A类型绑定一份方法

func (a A) test(){

    fmt.Println("test()",a.Num)

}

//主方法

func main(){

    var a A

    a.Num=10

    a.test() //调用

}

对上面的总结
1) test 方法和A类型绑定
2) test 方法只能通过A 类型的变量来调用,而不能直接调用,也不能使用其它类型变量来调用

3)func (a A) test(){ }  a表示哪个A变量调用,这个a就是它的副本,这点和函数传参非常相似。
4) a这个名字,可修改,不是固定。

方法的调用和传参机制原理
   在通过一个变量去调用方法时,其调用机制和函效一样,不-样的地方时,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类型,则进行值拷贝,如果变量是引用类型,则进行地址拷贝)

type circle struct{

    Radius  float64

}

func (c circle) area() float64 {

    return 3.14*c.Radius*c.Radius

}

//为了提高效率,通常我们方法和结构体的指针类型绑定

func (c *circle) area2() float64 {

    //因为c是指针,因此我们标准的访问其字段的方式是(*c).radius

    // (*c).Radius 等价于 c.Radius

    //return 3.14* (*c).Radius*(*c).Radius

    return 3.14* c.Radius*c.Radius

}

//主方法

func main(){

    var c circle

    c.Radius = 5.0

    res := c.area()

    fmt.Println("面积是=",res)

   var cc circle

    cc.Radius = 9.0

    //res2 := (&c).area2()

    //编译器底层做了优化 (&c).area2()等价c.area2()

    //因为编译器会自动的给加上&c

    res2 := cc.area2()

    fmt.Println("面积是=",res2)

}

方法的声明(定义)
func  (recevier type)  methodName  (参数列表)  (返回值列表) {
   方法体
return  返回值

}
1) 参数列表: 表示方法输入
2) recevier type : 表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
3) receiver type : type可以是结构体,也可以其它的自定义类型
4) receiver : 就是type类型的一个变量(实例),比如: Person结构体的一个变量(实例)
5) 参数列表:表示方法输入
6) 返回值列表: 表示返回的值,可以多个
7) 方法主体: 表示为了实现某一功能代码块
8) return 语句不是必须的。

方法注意事项和细节讨论
1) 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2) 如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
3) Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int , float32等都可以有方法
4) 方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
5) 如果一个类型实现了String()这个方法,那么fmt.PrintIn默认会调用这个变量的String()进行输出

/*

根据行、列、字符打印对应行数和列数的字符,

比如:行: 3,列: 2,字符*,则打印相应的效果

*/

type MethodUtils struct{

}

func (me MethodUtils) Print(n int, m int ,char string){

   

    for i :=0;i<n;i++{

        for j:=0;j<m;j++{

            fmt.Print(char)

        }

        fmt.Println()

    }

}

   var me MethodUtils

     me.Print(4,9,"~")

方法和函数区别
1) 调用方式不一样
      函数的调用方式:   函数名(实参列表)
     方法的调用方式:    变量.方法名(实参列表)
2) 对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
3) 对于方法(如struct的方法) ,接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以

注意:
1) 不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定.
2) 如果是值类型,比如(p Person),则是值拷贝,如果是指针类型, 比如是(p *Person)
是地址拷贝。

 //一个景区根据游人的年龄收取不同价格的门票,比如年龄大于18,收费20元,其它情况门票免费.

     //请编写Visitor结构体, 根据年龄段决定能够购买的门票价格并输出

     type Visitor struct{

        Name string

        Age int

    }

    func (v Visitor) beautiful(){

        var str string

        for {

           

            fmt.Println("请输入你的姓名")

            fmt.Scanln(&v.Name)

            fmt.Println("请输入你的年龄")

            fmt.Scanln(&v.Age)

   

            if v.Age > 18 {

                fmt.Printf("姓名: %v  年龄 : %v \n",v.Name,v.Age)

                fmt.Println("收费20")

            }else{

                fmt.Printf("姓名: %v  年龄 : %v \n",v.Name,v.Age)

                fmt.Println("免费进入")

            }

            fmt.Println("想退出程序输入n,否则按任意键继续")

            fmt.Scanln(&str)

            if str == "n"{

                break

            }

        }

    }

    var v Visitor

    v.beautiful()

创建结构体变量时指定字段值
Golang在创建结构体实例(变量)时,可以直接指定字段的值

第一种方式

在创建结构体变量时,就直接指定字段的值

    var vis1 = Visitor{"hello",57}

    vis2 := Visitor{"myfriend",16}

    //在创建结构体变量时,把字段名和字段值写在一起 这种写法,就不依赖字段的定义顺序。

     var vis3 = Visitor{

        Name:"heyhey",

        Age:55,

        }

    fmt.Println(vis1)

    fmt.Println(vis2)

    fmt.Println(vis3)

   

 第二种方式  返回结构体的类型

    var vis4 = &Visitor{"oop",99}  //vis4-->地址---》 结构体数 据[xxx,xxx]

    var vis5 = &Visitor{

        Name:"888",

        Age:18,

        }

        fmt.Println(*vis4)

        fmt.Println(*vis5)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值