zoukankan      html  css  js  c++  java
  • 从零开始学Go之函数(二):指针与方法

    类型别名与类型定义:

    类型别名:

    type 类型别名 = 类型名

    type TypeAlias = int

    TypeAlias 只是 int 的别名,本质上 TypeAlias 与 int 是同一个类型

    类型定义:

    type 新类型名 类型

    type NewInt int

    NewInt 则是一个新的类型,虽然他的实例化可以被赋值int,但是不再是int

    方法:

    Go 没有类。不过你可以为结构体类型或者非结构体类型定义方法。

    方法就是一类带特殊的接收者参数的函数。

    func (方法名 类型定义名) 函数名 (函数参数列表) (函数返回值列表){

    函数内部代码

    }

    type Vertex struct {
     X, Y float64
    }
    ​
    func (v Vertex) Abs() float64 {
     return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
    ​
    type MyInt int
    ​
    func (i MyInt) Abs() int {
     if i < 0 {
      return int(-i)
     }
     return int(i)
    }
    ​
    func main() {
     v := Vertex{3, 4}
     fmt.Println(v.Abs())
     i := MyInt(-2)
     fmt.Println(i.Abs())
    }

    运行结果:

    5

    -2

    此时,只有当实例化后,才能调用Abs()函数。两个Abs()函数对应的类型是不同的,所以调用的结果也不同

    方法只是个带接收者参数的函数。

    指针:

    简单解释一下,每个变量在运行时都会有一个在内存中的地址,而指针就是存储这个地址。

    声明:

    var [指针名] *[指针类型]

    var p *int//一个int类型的指针
     
    操作:

    从指针取值:取地址操作符“&”

    从值取地址:取值操作符“*”

     
    使用例子:
    func main() {
     var a int
     a = 1
     var b *int //或者是b:=new(int) 声明整型指针b
     b = &a  //b保存a的地址,即b指向a
     fmt.Println("a value=", a)
     fmt.Println("a address=", &a)
     fmt.Println("b address=", b)
     fmt.Println("b value=", *b)
     *b = 3 //通过指针修改值
     fmt.Println("a value=", a)
     fmt.Println("a address=", &a)
     fmt.Println("b address=", b)
     fmt.Println("b value=", *b)
    }
    a value= 1
    a address= 0xc0420080a8
    b address= 0xc0420080a8
    b value= 1
    a value= 3
    a address= 0xc0420080a8
    b address= 0xc0420080a8
    b value= 3

    可以发现地址没有改变,但是a和*b的值都同时改变了,由于b此时保存的是a的地址,当改变*b的值的时候实际就是在改变a的值。

     

    方法的指针:

    对于上一种方法,由于在函数中复制的是值,而本身没有改变,所以当需要改变实例化的结构体本身时,需要改变为方法的指针。

    func (方法名 *类型定义名) 函数名 (函数参数列表) (函数返回值列表){

    函数内部代码

    }

    type Vertex struct {
     X, Y float64
    }
    ​
    func (v Vertex) Abs() float64 {
     v.X=6
     v.Y=8
     return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
    ​
    func (v *Vertex) NewAbs() float64 {
     v.X=6
     v.Y=8
     return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
    ​
    func main() {
     v := Vertex{3, 4}
     fmt.Println(v.Abs(), v)
     fmt.Println(v.NewAbs(), v)//v的值已经改变
    }

    运行结果:

    10 {3 4}

    10 {6 8}

    这里需要注意的是NewAbs()中方法接收者是指针,虽然main函数中接受者v不是地址,但是Go会自动解释为(&v).NewAbs()

  • 相关阅读:
    Row versus Set Processing, Surprise!(集合处理和单行处理数据的差异性)
    SVN导出增量包的方法
    Number of Digit One
    VPS+LNMP+WordPress搭建个人网站
    寻找最小的k个数(大顶堆方法)
    二叉搜索树转化为有序双向链表(C语言)
    LeetCode 345 Reverse Vowels of a String
    LeetCode 278 First Bad Version
    LeetCode 205 Isomorphic Strings
    LeetCode 88 Merge Sorted Array
  • 原文地址:https://www.cnblogs.com/VingB2by/p/11117732.html
Copyright © 2011-2022 走看看