在Java中,复杂类型(除原始类型外的其它类)作为入参,在方法中被修改后,跳出方法对象内的值仍会保持,也就是传的是引用。原始类型传的是值,如int, double等原始类型。
Java代码:
public class Test { static class Vertex{ public double x; public double y; } static double abs(Vertex v) { return Math.sqrt(v.x * v.x + v.y * v.y); } static void scale(Vertex v, double f) { v.x = v.x * f; v.y = v.y * f; } public static void main(String[] args) { Vertex vertex = new Vertex(); vertex.x = 3; vertex.y = 4; System.out.println(abs(vertex)); // 5 scale(vertex, 10); System.out.println(abs(vertex)); // 50 } }
在Go中,对于结构体的方法,默认是传值,即对原值的副本进行操作,不会修改原值。如果用*T指定接收者,则可以修改接收者指定的值。由于方法经常需要修改它的接收者,指针接收者比值接收者更常用。
Go 代码:
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func (v *Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} v.Scale(10) fmt.Println(v.Abs()) // 50 }
如果把16行的*去掉,输出值是5,即不加*是传值,或者说传原值的副本;只有加上*才会修改原值。