美文网首页
11.Go语言·方法

11.Go语言·方法

作者: 一枼落知天下 | 来源:发表于2019-06-04 18:08 被阅读0次

    main.go

    // Go语言·方法
    package main
    
    //  包的本质是创建不同的文件夹
    //  go的每一个文件都是属于一个包的
    //  go以包的形式管理项目和文件目录。
    //  import "包的路径"
    import (
         utils "day20/model/utils" 
        _"fmt"
    )
    
    var content string = `
    ————————————————Go语言·方法————————————————————
    一、方法
    `
    
    
    func main() {
        utils.Entry()
    }
    

    utils.go

    // Go语言·方法
    package utils
    
    import (
        "fmt"
    )
    
    var layout string = "2006-01-02"
    
    // 全局变量
    var Author string = "Jhou Shuai"
    
    // 全局变量
    var Description string = "Go语言·方法"
    
    //全局变量:使用反引号来定义多行字符串
    var Content string = `
    ————————————————Go语言·方法————————————————————
    一、方法
        作用在指定的数据类型上的
        自定义类型都可以有方法
        type A struct {
            Num int
        }
    
        // 方法 : 结构体A的方法test
        func (a A) test (){}
    二、方法的调用和传参机制原理
           方法的调用和传参机制和函数基本一样,不一样的地方是方法调用
        时候会把调用函数的变量也会作为参数传入到方法中。
        如果变量是值类型,就进行值拷贝
        如果变量是引用类型,就进行地址拷贝
    三、方法的声明(定义)
        func (recevier type) methodName (参数列表) (返回值列表) {
            方法体
            return 返回值。
        }
        0.参数列表:表示方法传入的参数
        1.recevier type :表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
        2.recevier type :type可以结构体,也可以是其他的自定义数据类型
        3.recevier:就是type类型的一个变量(实例),比如:Person结构体的一个变量(实例)
        4.返回值列表:表示返回的值,可以多个
        5.方法主体:表示为了实现某一功能代码块
        6.return数据不是必须的
    四、方法的注意事项和细节讨论
        1.结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
        2.如果希望在方法中,修改结构体变量的值。可以通过结构体指针的方式来处理
        3.Golang中的方法作用在指定的数据类型上的。(即:和指定的数据类型绑定),因此自定义
        类型都可以有方法,而不仅是struct,比如:int,float32等都可以有方法。
        4.方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母
        大写,可以在本包和其他包访问。
        5.如果一个类型事项咯String()方法,那么fmt.Println默认会调用这个变量的String()进行
        输出
    五、函数和方法区别:
        1.调用方式不一样:
            函数调用:函数名(参数列表)
            方法调用:变量名(实例名).方法名(参数列表)
        2.对于普通的函数,接收者为值类型时,不能将指针类型的数据直接传递,接收者为指针类型时,
        不能将值类型的数据直接传递。
        3.对于方法:
            接收者为值类型时,可以直接用指针类型的变量调用方法,但任然是值拷贝传递方式
            接收者为指针类型时,可以用值类型的变量调用(编译器自动取地址),是引用传递,
                var person Person
                person.Name = "周帅"
                // 形式上是传入地址,但是本质任然是值拷贝
                (&person).structFuc()
                fmt.Println(person.Name)
                // 形式上是传入值类型,但是本质任然是地址拷贝
                person.Rename()
                fmt.Println(person.Name)
        总结:
            1.不管调用形式如何,真正决定是值拷贝还是地址拷贝,应该看方法和哪个类型绑定的
            2.如果方法是和值类型绑定,则是值拷贝 比如:
                func (person Person) structFuc() {}    #值拷贝  
            3.如果方法是和指针类型绑定,则是地址拷贝 比如:      
                func (person *Person) Rename() {}      #地址拷贝
    `
    
    type Person struct {
        Name string 
    }
    
    
    type Circle struct {
        radius float64
    }
    
    type Student struct {
        Name string
        Age int
    }
    
    
    type MethodUtils struct{
    
    }
    
    
    type Calcuator struct {
        Num1 float64
        Num2 float64
    }
    
    /**
     * [Init 入口]
     * @author Jhou Shuai
     * @datetime 2019-05-18T11:58:33+0800
     */
    func Entry() {
        var person Person
        person.Name = "周帅"
        // 形式上是传入地址,但是本质任然是值拷贝
        (&person).structFuc()
        fmt.Println(person.Name)
        // 形式上是传入值类型,但是本质任然是地址拷贝
        person.Rename()
        fmt.Println(person.Name)
    }
    
    
    /**
     * [func 给Person类型绑定一个方法]
     * 给Person类型绑定一个方法
     * structFuc方法只能通过Person类型的变量来调用,而不能直接调用,也不能用其他变量调用
     * @author Jhou Shuai
     * @datetime 2019-06-03T20:23:24+0800
     *  var person Person
        person.Name = "周帅"
        fmt.Println(person.getSum(100,20))
     */
    func (person Person) structFuc() {
        person.Name = "小可爱"
        fmt.Println(person.Name)
    }
    
    
    func (person *Person) Rename() {
        person.Name = "小宝贝儿"
        fmt.Println(person.Name)
    }
    
    
    func (person Person) speak() {
        fmt.Printf("%v是一个好人!",person.Name)
    }
    
    
    func (person Person) sum(n int) {
        res := 0
        for i:=1;i<=n;i++{
            res +=i
        }
        fmt.Println(res)
    }
    
    func (person Person) getSum(n1 int,n2 int) int {
        return  n1 + n2
    }
    
    
    /*
        var circle Circle
        circle.radius = 6.0
        // fmt.Println((&circle).area())
        // 编译器:会自动加上&
        fmt.Printf("circle变量的地址:%p \n", &circle)
        fmt.Println(circle.area())
        fmt.Println(circle.radius)
     */
    func (circle *Circle) area() float64 {
        circle.radius = 10
        fmt.Printf("circle指向的地址:%p \n", circle)
        // return 3.14 * (*circle).radius * (*circle).radius
        return 3.14 * circle.radius * circle.radius
    }
    
    
    /*
    stu := Student{
            Name:"Faker",
            Age : 19,
        }
        fmt.Println(&stu)
     */
    func (stu *Student) String() string {
        str := fmt.Sprintf("Name=[%v] Age=[%v] \n",stu.Name,stu.Age)
        return str
    }
    
    
    /*
        var mu MethodUtils
        res := mu.area(2.5,6.7)
        fmt.Println(res)
        mu.JudgeNum(233)
        mu.PrintFlower(5, 5, "~")
     */
    
    func (mu *MethodUtils) area (len float64,width float64) float64 {
        return  len * width
    }
    
    func (mu *MethodUtils) JudgeNum (num int) {
        if num%2 == 0 {
            fmt.Println(num,"偶数")
        }else{
            fmt.Println(num,"奇数")
        }
    }
    
    
    func (mu *MethodUtils) PrintFlower(n int ,m int, flower string) {
        for i := 1; i <=n; i++ {
            for j := 1; j <=m; j++ {
                fmt.Print(flower)
            }
            fmt.Println()
        }
    }
    
    /*
    九九乘法表
     */
    func (mu *MethodUtils) NineTable() {
        var num int
        fmt.Print("请输入一个数>>> ")
        fmt.Scanln(&num)
        for i := 1; i <= num ; i++ {
            for j := 1; j <= i; j++ {
                fmt.Printf("%v×%v=%v\t",j,i,i*j)
            }
            fmt.Println()
        }
    }
    
    /*
    用二维数组实现矩阵的转置
     */
    func (mu *MethodUtils) Tranfer() {
    
        var intArr [3][3]int = [...][3]int{{1,2,3},{4,5,6},{7,8,9}}
        
        for _,values := range intArr {
            for _ ,val := range values {
                fmt.Print(val," ")
            }
            fmt.Println()
        }
    
        for i := 0; i < 3; i++ {
            for j := 0; j <3; j++ {
                fmt.Printf("%d ",intArr[j][i])
            }
            fmt.Println()
        }
    }
    
    
    /*
    var cal Calcuator
        cal.Num1 = 3.3
        cal.Num2 = 1.5
        res := fmt.Sprintf("%.2f", cal.getRes('*'))
        fmt.Println(res)
     */
    func (calcuator *Calcuator) getRes(operator byte) float64 {
        res := 0.0
        switch operator{
            case '+':
                res = calcuator.Num1 + calcuator.Num2
            case '-':
                res = calcuator.Num1 - calcuator.Num2
            case '*':
                res = calcuator.Num1 * calcuator.Num2
            case '/':
                res = calcuator.Num1 / calcuator.Num2
            default:
                fmt.Println("输入有误!")
        }
        return res
    }
    

    相关文章

      网友评论

          本文标题:11.Go语言·方法

          本文链接:https://www.haomeiwen.com/subject/uqprxctx.html