使用方法而不是函数有什么好处?

时间:2019-10-01 06:17:00

标签: function go methods

我正在出于练习Go的目的而开发“ Matrix”结构和相关方法。 我做了很多方法,但是我意识到所有这些方法都可以变成函数 我已经习惯了C ++,在C ++中,如果我制作了一个参数为类类型的函数,该函数将无法使用该类的私有变量(信息隐藏) 但是,当我使用“ Go”构建类似的代码时,函数可以访问结构的变量。 所以我没有得到Go中方法和函数之间的区别。 使用方法而不是功能会产生任何利润,反之亦然吗?

第一个是我原始的“矩阵”代码(不是全部) 它使用方法“ Tr”。 它没有问题。

package main
import "fmt"

//definition of "Array"
type Array struct{
    component [][]float32
    row int
    col int
}
//constructor of Array, "Ones"; making an array setting all component as one
func Ones(m int, n int) Array{
    var a Array
    a.component = make([][]float32, m)
    a.row=m
    a.col=n
    for i:=0; i<m; i++{
        a.component[i] = make([]float32, n)
        for j:=0; j<n; j++{
            a.component[i][j]=1
        }
    }
    return a
}
//Tr function; find trace of an Array
func (a Array) Tr() float32{
    var sum float32 = 0
    for i:=0; i<a.row; i++{
        sum += a.component[i][i]
    }
    return sum
}

func main(){
    a := Ones(3,3)
    fmt.Println(a.Tr())
}

第二个是另一个类似的代码。 (除“ Tr”部分外其他所有内容均相同) 它仅使用功能。 它也没有问题。

package main
import "fmt"

//definition of "Array"
type Array struct{
    component [][]float32
    row int
    col int
}
//constructor of Array, "Ones"; making an array setting all component as one
func Ones(m int, n int) Array{
    var a Array
    a.component = make([][]float32, m)
    a.row=m
    a.col=n
    for i:=0; i<m; i++{
        a.component[i] = make([]float32, n)
        for j:=0; j<n; j++{
            a.component[i][j]=1
        }
    }
    return a
}
//Tr function; find trace of an Array
func Tr(a Array) float32{
    var sum float32 = 0
    for i:=0; i<a.row; i++{
        sum += a.component[i][i]
    }
    return sum
}

func main(){
    a := Ones(3,3)
    fmt.Println(Tr(a))
}

1 个答案:

答案 0 :(得分:4)

如果只想调用函数或方法,没关系,您可以创建一个带有签名的函数,其中接收者是正常的常规参数。不会有任何性能损失(方法可能是virtual,但在Go中没有虚拟方法)。

一个优势可能是“视觉吸引力”。调用方法很明显它属于接收方。如果使用方法,我还会发现链接代码更容易理解。

比较不带方法的此解决方案:

select id,name,max(total_score) over (partition by name)  max_score from (
select id,name,sum(score) as total_score from YOURTABLE
group by id,name
) t

type Circle struct{} type Point struct{} func Center(Circle) Point { return Point{} } func Abs(Point) float64 { return 0 } func main() { var c Circle fmt.Println(Abs(Center(c))) } 不是那么直观。但是,如果您添加方法而不是使用函数:

Abs(Center(c))

func (Circle) Center() Point { return Point{} } func (Point) Abs() float64 { return 0 } func main() { var c Circle fmt.Println(c.Center().Abs()) } 更容易理解。

如果要实现接口,则必须使用方法。如果接口包含某些方法,则只有具有那些方法的类型才能实现它。请参阅相关内容:Why are interfaces needed in Golang?还应注意,您只能创建在同一程序包中定义的方法,因此,如果您要“武装”来自其他程序包的类型,则不能“使用”方法。 / p>

使用方法时,我会称其为“利润”:您不能按名称调用函数,但是可以按名称访问和调用方法。有关详细信息,请参见Call functions with special prefix/suffix