golang golang - sliceの重复を削除

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang golang - sliceの重复を削除相关的知识,希望对你有一定的参考价值。

// sliceの重複要素を削除
func slimSlice(slice []int) []int {
	m := make(map[int]int)
	slim := make([]int, 0)
	for _, element := range slice {
		if _, ok := m[element]; !ok {
			m[element] = 0
			slim = append(slim, element)
		}
	}
	return slim
}

golang中Array与Slice

在golang中有数组和Slice两种数据结构,Slice是基于数组的实现,是长度动态不固定的数据结构,本质上是一个对数组字序列的引用,提供了对数组的轻量级访问。那么在go的函数中以数组或Slice为形参的时候就存在一些差别。

? 首先,golang中是值传递,并且如果传递的参数是数组的时候并不会隐式将数组作为引用或者指针传入,而是传入副本,而如果想轻量级传递数据,这个时候就需要使用slice了。

可以通过一个简单的例子来验证这个机制:

package main

import "fmt"

func main()  {
    array := [4]int{1, 2, 3, 4}
    fmt.Printf("实参array地址:%p\n", &array)
    printArray(array)
    printSlice(array[0:4])
}

func printArray(array [4]int)  {
    fmt.Printf("形参array地址:%p\n", &array)
    for _, e := range array {
        fmt.Print(e)
    }
    fmt.Println()
}

func printSlice(array []int)  {
    fmt.Printf("形参slice地址:%p\n", &array)
    for _, e := range array {
        fmt.Print(e)
    }
    fmt.Println()
}

运行结果如下:

实参array地址:0xc0000480a0
形参array地址:0xc0000480e0
1234
形参slice地址:0xc000044420
1234

运行结果表明,如果形参是数组的话,那么相当于传递的是一份数组的拷贝,形参和实参的地址均相同,而如果形参是slice的话,传递的则是引用而不是拷贝。

同时,如果形参是数组,那么Slice变量是无法传入的,反之亦然。

另外,数组的几种定义方式也有区别:

例如[...]int{1,2,3,4}这是一个数组,能够printArray([...]int{1,2,3})printSlice([...]int{1,2,3}[0:1]) 这两种方式使用,而[]int{}则实际上是一个slice,所以可以printSlice([]int{}),但是如果printArray([]int{})则编译器会报错。所以定义数组的时候如果指定了长度或者[...]int{1,2,3}这种自动初始化长度的情况则返回的是数组,而如果没有指定长度则返回的是slice。

结论:如果要传递拷贝则使用数组作为形参,如果要传递引用则使用slice作为形参。定义数组需要指定长度,定义slice不能指定长度(或者使用make定义)。

以上是关于golang golang - sliceの重复を削除的主要内容,如果未能解决你的问题,请参考以下文章

golang golang_array_slices_maps

Golang Clearing slice

golang变量(二)——map和slice详解

golang的slice了解及验证

Golang Array and Slice

golang中Array与Slice