# 1.javascript 与 Golang 中类型的异同:数组篇

# JS(数组)Vs Golang(数组 && 切片)

设现有变量 a,b, 进行赋值操作 JS(a = b),Golang(a := b);

# a = b,变量赋值,改变 b,是否会改变 a 的值?

  1. JS 数组 和 Golang切片

    1. 它们存储在堆内存中,单纯的赋值,都是指向同一个数组对象内存空间,修改 b 会同时改变 a
    2. 都是动态数组,会根据传入值的数量增加数组最大容量。
  2. JS 数组 和 Golang数组

    1. 虽然 Golang 数组也是引用类型,但是 Golang 数组的赋值,实际上是将整个数组复制一份,两个变量指向的数据是两个独立的对象,修改其中一个变量所指向的数组不会影响到另一个变量。
    // js数组
    let arr1 = [1, 2, 3];
    let arr2 = arr1;
    arr2.push(4);
    console.log(arr1); // [1, 2, 3, 4]
    console.log(arr2); // [1, 2, 3, 4]
    
    1
    2
    3
    4
    5
    6
    // Golang切片
    s1: = [] int {
       1,
       2,
       3
    }
    s2: = s1
    s2 = append(s2, 4)
    fmt.Println(s1) // [1 2 3 4]
    fmt.Println(s2) // [1 2 3 4]
    
    // Golang数组
    arr1: = [3] int {
       1,
       2,
       3
    }
    arr2: = arr1
    arr2[1] = 4
    fmt.Println(arr1) // [1 2 3]
    fmt.Println(arr2) // [1 4 3]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

# Golang 中数组的方法

  1. Golang 数组
    • 定义: var a [5]int // 定义一个长度为 5 的整型数组 a
    • 遍历: for i, v := range a { ... }
    • 追加:Golang 中,数组的长度是固定的,不能进行动态增长或缩小,但是可以通过将数组转换成切片,执行切片的追加操作,并将结果重新赋值给新的数组,实现类似于追加的效果。
    • 复制: copy(dst, src []T) int
    • 剪切: a[low:high](low、high 都是可选的,默认零值为开头和结尾)
  2. Golang 切片
    • 定义: var s []int,s := make([]int, 5),s := []int{1,2,3,4,5}
    • 遍历: for i, v := range s { ... }
    • 追加: append(s []T, vs ...T) []T
    • 复制: copy(dst, src []T) int
    • 剪切: s[low:high:limit](low、high 都是可选的,默认零值为开头和结尾,limit 是指定新切片的容量)

# copy 和 make

  1. copy(用于切片或者数组)
    1. copy 的第一个参数是目标切片或数组,第二个参数是源切片或数组。
    2. 如果两个参数都是切片,则 copy 只复制两个切片之间的共同长度部分。
    3. 如果目标参数是数组,则只会复制到数组的长度为止,超过部分会被截断。
    4. 返回复制的元素个数(即两个切片中较短的那个)
  2. make(用于创建切片、映射和通道等动态数据结构
    1. 其参数分别为类型、长度和容量(仅适用于切片和通道类型)
    2. 返回创建的新切片
package main
import "fmt"
func main() {
    a := []int{1, 2, 3, 4, 5}
    b := make([]int, len(a)) // 创建一个和 a 长度相同的新切片 b
    n := copy(b, a)          // 将 a 中的元素复制到 b 中,并返回复制的元素个数
    fmt.Println(a, b, n)     // 输出:[1 2 3 4 5] [1 2 3 4 5] 5

    s := make([]int, 3, 5) // 创建一个长度为 3、容量为 5 的切片 s
    fmt.Println(s, len(s), cap(s)) // 输出:[0 0 0] 3 5
}
1
2
3
4
5
6
7
8
9
10
11
  1. 是否会影响原数组

    1. 使用 copy 和 make 生成的新数组或切片和原数组或切片是独立的,它们之间的修改不会相互影响。
    2. 但是:如果数据是指针类型,则 copy 函数只会复制指针,而不会复制指针指向的数据,因此对其中一个数组/切片进行修改,会影响另外一个数组/切片指向的数据。
    package main
    
    import "fmt"
    
    func main() {
       a := [5]int{1, 2, 3, 4, 5}
       b := make([]int, len(a))
       copy(b, a[:])
    
       a[0] = 10
       b[1] = 20
    
       fmt.Println(a) // 输出:[1 2 3 4 5]
       fmt.Println(b) // 输出:[1 20 3 4 5]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
Last Updated: 6/3/2024, 1:08:34 AM