zoukankan      html  css  js  c++  java
  • Go语言中的方法(Method Sets)

     

    物以类聚,人以群分。事物必以类分,以形命名。开始一个个学习Go语言中有哪些数据类型,以及这些类型的特点。

    Go语言中的方法是函数之外一个特别的概念。在Go语言的参考中说:

    A type may have a method set associated with it (§Interface types, §Method declarations).

    1. The method set of an interface type is its interface.
    2. The method set of any other type T consists of all methods with receiver type T.
    3. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).
    4. Any other type has an empty method set.
    5. In a method set, each method must have a unique method name.

    意即,可以为所有自己定义的数据类型定义和该类型相关的方法。在Go里面没有严格的对象的概念,却有方法的概念。两个特殊的地方是:
    1. interface是一个抽象的数据类型,它本身就是一个方法集。
    2. 要注意type *T和type T不一样。实践中发现区别只在于指针上,type *T的方法操作原数据,type T的方法操作原数据的一个拷贝。type *T和type T定义的方法能互相用,不能重名。
    3. 所有方法必需有单独的名字,并且不能动态重载。要完成动态重载可以用interface。

    下面这个例子给自定义的浮点数建立Abs()方法:

    package main

    import (
        "fmt"
        "math"
    )

    type MyFloat float64

    func (f MyFloat) Abs() float64 {
        if f < 0 {
            return float64(-f)
        }
        return float64(f)
    }

    func main() {
        f := MyFloat(-math.Sqrt2)
        fmt.Println(f.Abs())
    }
    下面这个例子给结构体和结构体指针定义两个方法:
    package main

    import (
        "fmt"
        "math"
    )

    type Vertex1 struct {
        X, Y float64
    }

    func (v Vertex1) Scale(f float64) {
        v.X = v.X * f
        v.Y = v.Y * f
    }

    func (v Vertex1) Abs() float64 {
        return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }

    //不能再定义方法(v *Vertex1) Abs() float64 

    type Vertex2 struct {
        X, Y float64
    }

    func (v *Vertex2) Scale(f float64) {
        v.X = v.X * f
        v.Y = v.Y * f
    }

    func (v *Vertex2) Abs() float64 {
        return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }

    func main() {
        v1 := Vertex1{3, 4}
        v1.Scale(5)
        fmt.Println(v1, v1.Abs())

        pv1 := &Vertex1{3, 4}
        pv1.Scale(5)
        fmt.Println(pv1, pv1.Abs())

        v2 := Vertex2{3, 4}
        v2.Scale(5)
        fmt.Println(v2, v2.Abs())

        pv2 := &Vertex2{3, 4}
        pv2.Scale(5)
        fmt.Println(pv2, pv2.Abs())
    }
    /*
      will out put:
      {3, 4} 5
      &{3, 4} 5
      {15, 20} 25
      &{15, 20} 25
    */
  • 相关阅读:
    一类分治问题
    [POI2005]DWU-Double-row
    [SCOI2007]降雨量
    [POI2007]ODW-Weights(贪心)
    bzoj3427小P的牧场(斜率优化dp)
    UVA10559 Blocks(区间dp)
    LOJ6089 小Y的背包计数问题(根号优化背包)
    [APIO2008]免费道路(生成树)
    bzoj4383(拓扑排序)
    [HEOI2014]平衡(整数划分数)
  • 原文地址:https://www.cnblogs.com/damir/p/2486523.html
Copyright © 2011-2022 走看看