Go中的数组是按值计算的吗?

时间:2018-07-05 03:29:11

标签: arrays go deep-copy

$( ".sidenav span" ).click(function() {
  var index = $(this).data('index');

  $( ".container" ).each(function(i) {
    if (i != index) {
        $(this).addClass('hidden');
    }
    else {
        $(this).removeClass('hidden');
    }
  });
});

从上面进行测试,看来Go中的数组是按值而不是引用传递的。因此,我可以得出结论,在Go中处理此类问题时,不需要package main import ( "fmt" ) func main() { var a = [5]int{1,2,3,4,5} b := a b[4] = 100 fmt.Println(a,b) //[1 2 3 4 5] [1 2 3 4 100] } 也不需要shallow-copying的概念吗?

3 个答案:

答案 0 :(得分:8)

  

The Go Programming Language Specification

     

Array types

     

数组是单个类型的编号元素序列,称为   元素类型。元素的数量称为长度,且为   永远不会消极。

     

长度是数组类型的一部分;它必须评估为   可通过类型int的值表示的非负常数。长度   可以使用内置函数len查找数组a的数组。的   元素可以通过整数索引0到len(a)-1进行寻址。

     

Slice types

     

切片是基础层连续段的描述符   数组,并提供对该数组中元素编号序列的访问   数组。切片类型表示其所有数组切片的集合   元素类型。未初始化的片的值为nil。

     

像数组一样,切片是可索引的并且具有长度。一个的长度   可以通过内置函数len查找slice;不像   在执行期间可能会更改的数组。元素可以解决   整数索引0到len(s)-1。给定的切片索引   元素可能小于相同元素在索引中的索引   基础数组。

     

切片一旦初始化,便始终与基础   包含其元素的数组。因此,切片与   它的数组以及同一个数组的其他切片;相比之下,   不同的数组始终代表不同的存储。

     

切片下面的数组可能会延伸到切片的末尾。的   能力是该程度的度量:它是长度的总和   切片以及超出切片的数组的长度;一片   可以通过从中切片一个新的来创建最大容量的长度   原始切片。切片a的容量可以使用   内置功能帽(a)。


您应该将Go数组与Go切片进行比较。分配复制数组值。分配复制切片描述符值。切片描述符是具有长度,容量和指向其基础切片数组的指针的结构。

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

例如,

package main

import "fmt"

func main() {
    // array
    var a = [5]int{1, 2, 3, 4, 5}
    b := a
    b[4] = 100
    fmt.Println(a, b)

    // slice
    var s = []int{1, 2, 3, 4, 5}
    t := s
    t[4] = 100
    fmt.Println(s, t)
}

游乐场:https://play.golang.org/p/8eFa1Mod_Kj

输出:

[1 2 3 4 5] [1 2 3 4 100]
[1 2 3 4 100] [1 2 3 4 100]

答案 1 :(得分:2)

Go中的所有内容始终按值传递,即使使用了指针,它也会复制该指针的8个字节。

答案 2 :(得分:2)

Go中的所有内容都按值传递(Go中没有“按引用传递”的概念)。

当所有内容都按值传递时,将对其进行复制。指针的副本只是地址的副本,而不是“深层副本”。因此,没有直接或隐藏指针的对象的副本将是深层副本,而具有显式或隐式指针的对象的副本将是浅层副本。

数组不包含指针,因此,如果您的Array元素不包含指针,则将获得深层副本。

切片和通道以及地图 do 包含(隐藏)指针,将其复制将为您提供切片(通道,地图)的副本,但是浅表:内部的内容不会被复制因为它们不是切片的直接部分(切片包含指向实际数据的指针)。

因此,Go中存在深层复制和浅层复制的概念。粗略地讲:一切都是深层复制,指针的深层复制只是地址的副本(而不是指针):深度复制在指针处停止(甚至像切片中一样隐藏在语言中)。

与往常一样,当指针在Go中显式显示时,复制的内容非常明显且确定。