使用方法(method)相比普通函数调用有什么优势?

huangapple go评论92阅读模式
英文:

What advantage we get using method than a regular funtion call

问题

我们可以将结构体作为参数传递给函数,而不是方法。那么在Go语言中,方法的意义是什么?有人可以用例子来解释吗?

简单来说,我想知道一个情况,即“方法可以执行哪些函数无法实现的操作”,或者方法逻辑有什么好处。

使用结构体的方法或函数调用的示例代码:

package main

import (
	"fmt"
)

type Person struct {
	name string
	age  int
}

// 函数接受结构体参数
func functionCall(first Person) {
	fmt.Println("普通函数调用", first)
}

// 方法调用结构体类型
func (second Person) methodCall() {
	fmt.Println("方法函数调用", second)
}

func main() {
	p1 := Person{"satish", 23}
	p1.name = "kumar"
	functionCall(p1)
	p1.name = "Yes"
	p1.methodCall()
}

输出结果:
普通函数调用 {kumar 23}
方法函数调用 {Yes 23}

英文:

We can pass a struct to a function as a argument than a method. Then what is the significance of method in Go? Can anyone explain with example

In simple terms I'm curious to know a case where, " A method can perform which is not possible to implement using function." or what benefit with method logic.

Sample code for method or function call using struct
package main

import (
	“fmt”
)

type Person struct {
	name string
	age int
}

// Function takes struct argument
func functionCall(first Person) {
	fmt.Println(“Normal Funtion call”, first)
}

//Method call on struct type
func (second Persoan) methodCall() {
	fmt.Println(“Method Function call”, second)
}

func main() {
	p1 := Person{“satish”, 23}
	p1.name = “kumar”
	functionCall(p1)
	p1.name = “Yes”
	p1.methodCall()
}
Output:
Normal Funtion call {kumar 23}
Method Function call {Yes 23}

答案1

得分: 2

正如Cerise所提到的,方法的“USP”是它们与接口绑定,并且可以让你编写“面向对象”的代码(为了完整起见,结构体嵌入也可以让你编写“面向对象”的代码)。

以经典的Stringer接口为例,你的“Person”类型可以通过实现String()方法来实现Stringer接口。请参考以下代码示例:https://tour.golang.org/methods/17

现在,这样做的原因(而不是编写一个函数)是,任何“Person”类型的实例现在都可以作为参数传递给接受Stringer作为输入的代码。举个高度简化的例子,假设在某个库中有一个函数提供了一些非常复杂的行为,你需要调用它。但是这个函数接受Stringer类型的参数:

func SomeComplexFunction(s Stringer) {
    //一些复杂的代码
}

如果“Person”实现了String()方法,你可以将Person的实例传递给这个假设的函数:

p1 := Person{"satish", 23}
SomeComplexFunction(p1)

显然,复杂函数并不知道你的Person类型,但由于Person实现了Stringer接口(通过实现Stringer的方法),它可以与之一起工作。在某些情况下,你可以通过传递函数作为参数(类似于“C”风格的函数指针)来实现相同的效果...但这样做可能会增加代码的复杂性。

举个更“现实世界”的例子,假设你有表示商店中不同产品的类型,并且有一个Shipment Processor来处理发货。为了避免每次添加新产品时都必须更改发货代码,最好使用一个带有方法的接口来提供这种抽象。

type MobilePhone struct {
    //字段
}

func (o *MobilePhone) GetWeight() float64 {
    //返回产品的重量
}

type Toy struct {
    //字段
}

func (o *Toy) GetWeight() float64 {
    //返回产品的重量
}

type IShippable interface {
    GetWeight() float64
    //其他与发货相关的方法
}

ShipmentProcessor(shipment IShippable) {
    //处理发货的代码
}
英文:

As Cerise mentioned, the 'USP' of methods is the fact that they are tied to interfaces and let you write 'object-oriented' code (for sake of completeness, struct embedding also lets you write 'object-oriented' code).

Taking the classic Stringer interface as an example, your 'Person' type can implement the Stringer interface merely by implementing a String() method. See this code example: https://tour.golang.org/methods/17

Now, the reason to do it this way (instead of writing a function) is that any instance of the 'Person' type can now be passed as an argument to code that accepts Stringer as input. To take a highly simplified example, let's assume there is some function in some library which provides some very complex behaviour which you need to call. But this function accepts args of type Stringer:

func SomeComplexFunction (s Stringer) {
    //some complex code
}

If 'Person' implements String(), you can pass instances of Person to this hypothetical function

p1 := Person{“satish”, 23}
SomeComplexFunction(p1)

The complex function is obviously not aware of your Person type, but can work with it due to the fact that Person implements the Stringer interface (by implementing Stringer's methods). In some cases, you could achieve the same by passing function as arguments ('C' style function pointers)... but the code complexity can go up a bit in doing so.

To take a more 'real-world' example, let's say you had types representing different products in a store and a Shipment Processor to handle shipments. To avoid having to change your shipment code every time you add a new product, you're best off using an interface (with methods) to provide this abstraction.

type MobilePhone struct {
    //fields 
}

func (o *MobilePhone) GetWeight() float64 {
    //return the product's weight
}

type Toy struct {
    //fields
}

func (o *Toy) GetWeight() float64 {
    //return the product's weight
}

type IShippable interface {
    GetWeight() float64
    //other shipment related methods
}

ShipmentProcessort(shipment IShippable) {
    //code to process shipment
}

答案2

得分: 1

函数 - 一组执行任务的指令。
方法 - 一组与对象相关联的指令。

您可以使用方法来传达逻辑/函数的所有权。如果您想要实现一个接口,方法也会有所帮助。

英文:

Function — a set of instructions that perform a task.
Method — a set of instructions that are associated with an object.

You can use method to convey the ownership of logic/function. It can also help if you want to implement and interface.

huangapple
  • 本文由 发表于 2021年11月1日 14:26:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/69793276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定