在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,即不加*是传值,或者说传原值的副本;只有加上*才会修改原值。
12-28 13:56