Go 就地更改函数内的切片内容和容量

Go 就地更改函数内的切片内容和容量,go,slice,in-place,Go,Slice,In Place,我正在尝试学习围棋,因此下面是我的一个非常简单的函数,用于从Donovan&Kernighan的书中删除用于练习的切片中相邻的重复项。 代码如下: 主程序包 输入“fmt” func main(){ a:=[]int{0,1,1,3,3} 移除(a) fmt.Println(a) } func removeDup(s[]int){ n:=len(s) tmp:=make([]int,0,n) tmp=append(tmp,s[0]) j:=1 对于i:=1;i

我正在尝试学习围棋,因此下面是我的一个非常简单的函数,用于从Donovan&Kernighan的书中删除用于练习的切片中相邻的重复项。
代码如下:

主程序包
输入“fmt”
func main(){
a:=[]int{0,1,1,3,3}
移除(a)
fmt.Println(a)
}
func removeDup(s[]int){
n:=len(s)
tmp:=make([]int,0,n)
tmp=append(tmp,s[0])
j:=1
对于i:=1;i
它应该打印出
[0 1 3]
-我在函数末尾检查了
tmp
,它具有所需的形式。但是,结果是
[01 3]
。我想是有了
copy
功能


我可以用
temp
替换输入片
s
,或者将其修剪到所需的长度吗?

选项1

返回@zerkms建议的新切片。

主程序包
输入“fmt”
func main(){
a:=[]int{0,1,1,3,3}
a=移除(a)
fmt.Println(a)
}
func removeDup(s[]int)[]int{
n:=len(s)
tmp:=make([]int,0,n)
tmp=append(tmp,s[0])
对于i:=1;i
选项2
使用指针按引用传递。
与选项1的效果相同

主程序包
输入“fmt”
func main(){
a:=[]int{0,1,1,3,3}
移除(&a)
fmt.Println(a)
}
func removeDup(sp*[]int){
s:=*sp
n:=len(s)
tmp:=make([]int,0,n)
tmp=append(tmp,s[0])
对于i:=1;i
另外,请参阅以下SO螺纹:

选项1

返回@zerkms建议的新切片。

主程序包
输入“fmt”
func main(){
a:=[]int{0,1,1,3,3}
a=移除(a)
fmt.Println(a)
}
func removeDup(s[]int)[]int{
n:=len(s)
tmp:=make([]int,0,n)
tmp=append(tmp,s[0])
对于i:=1;i
选项2
使用指针按引用传递。
与选项1的效果相同

主程序包
输入“fmt”
func main(){
a:=[]int{0,1,1,3,3}
移除(&a)
fmt.Println(a)
}
func removeDup(sp*[]int){
s:=*sp
n:=len(s)
tmp:=make([]int,0,n)
tmp=append(tmp,s[0])
对于i:=1;i
另外,请参阅以下SO螺纹:

这里还有两种稍微不同的方法,可以使用集合和命名类型实现您想要的功能。命名类型最酷的地方在于,您可以围绕它们创建接口,并有助于提高大量代码的可读性

package main

import "fmt"

func main() {
    // returning a list
    a := []int{0, 1, 1, 3, 3, 3}
    clean := removeDup(a)
    fmt.Println(clean)
    // creating and using a named type
    nA := &newArrType{0, 1, 1, 3, 3, 3}
    nA.removeDup2()
    fmt.Println(nA)

    // or... casting your orginal array to the named type
    nB := newArrType(a)
    nB.removeDup2()
    fmt.Println(nB)
}

// using a set
// order is not kept, but a set is returned
func removeDup(s []int) (newArr []int) {
    set := make(map[int]struct{})
    for _, n := range s {
        set[n] = struct{}{}
    }
    newArr = make([]int, 0, len(set))
    for k := range set {
        newArr = append(newArr, k)
    }
    return
}

// using named a typed
type newArrType []int

func (a *newArrType) removeDup2() {
    x := *a
    for i := range x {
        f := i + 1
        if f < len(x) {
            if x[i] == x[f] {
                x = x[:f+copy(x[f:], x[f+1:])]
            }
        }
    }
    // check the last 2 indexes
    if x[len(x)-2] == x[len(x)-1] {
        x = x[:len(x)-1+copy(x[len(x)-1:], x[len(x)-1+1:])]
    }
    *a = x
}
主程序包
输入“fmt”
func main(){
//返回列表
a:=[]int{0,1,1,3,3}
清洁:=移除(a)
fmt.Println(清洁)
//创建和使用命名类型
nA:=&newArrType{0,1,1,3,3}
nA.removeDup2()
fmt.Println(北美)
//或者…将原始数组强制转换为命名类型
注:=newArrType(a)
注意:removeDup2()
fmt.Println(nB)
}
//使用一套
//不保留订单,但返回一个集合
函数删除(s[]int)(newArr[]int){
set:=make(映射[int]结构{})
对于u,n:=范围s{
集合[n]=struct{}{}
}
newArr=make([]整数,0,len(集))
对于k:=范围集{
newArr=append(newArr,k)
}
返回
}
//使用命名的
类型newArrType[]int
func(a*newArrType)removeDup2(){
x:=*a
对于i:=范围x{
f:=i+1
如果f
这里还有两种稍有不同的方法,可以使用集合和命名类型实现您想要的功能。命名类型最酷的地方在于,您可以围绕它们创建接口,并有助于提高大量代码的可读性

package main

import "fmt"

func main() {
    // returning a list
    a := []int{0, 1, 1, 3, 3, 3}
    clean := removeDup(a)
    fmt.Println(clean)
    // creating and using a named type
    nA := &newArrType{0, 1, 1, 3, 3, 3}
    nA.removeDup2()
    fmt.Println(nA)

    // or... casting your orginal array to the named type
    nB := newArrType(a)
    nB.removeDup2()
    fmt.Println(nB)
}

// using a set
// order is not kept, but a set is returned
func removeDup(s []int) (newArr []int) {
    set := make(map[int]struct{})
    for _, n := range s {
        set[n] = struct{}{}
    }
    newArr = make([]int, 0, len(set))
    for k := range set {
        newArr = append(newArr, k)
    }
    return
}

// using named a typed
type newArrType []int

func (a *newArrType) removeDup2() {
    x := *a
    for i := range x {
        f := i + 1
        if f < len(x) {
            if x[i] == x[f] {
                x = x[:f+copy(x[f:], x[f+1:])]
            }
        }
    }
    // check the last 2 indexes
    if x[len(x)-2] == x[len(x)-1] {
        x = x[:len(x)-1+copy(x[len(x)-1:], x[len(x)-1+1:])]
    }
    *a = x
}
主程序包
输入“fmt”
func main(){
//返回列表
a:=[]int{0,1,1,3,3}
清洁:=移除(a)
fmt.Println(清洁)
//创建和使用命名类型
nA:=&newArrType{0,1,1,3,3}
nA.removeDup2()
fmt.Println(北美)
//或者…将原始数组强制转换为命名类型
注:=newArrType(a)
注意:removeDup2()
fmt.Println(nB)
}
//使用一套
//不保留订单,但返回一个集合
函数删除(s[]int)(newArr[]int){
set:=make(映射[int]结构{})
对于u,n:=范围s{
集合[n]=struct{}{}
}
newArr=make([]整数,0,len(集))
对于k:=范围集{
newArr=append(newArr,k)
}
返回
}
//使用命名的
类型newArrType[]int
func(a*newArrType)removeDup2(){
x:=*a
对于i:=范围x{
f:=i+1
如果f
removeDup
应返回新切片。
removeDup
应返回新切片。我知道返回新切片并将其分配给先前声明的切片将完成此工作,但我希望在函数中完成此操作。指针似乎是理想的解决方案,谢谢!我有
package main

import "fmt"

func main() {
    a := []int{0, 1, 1, 3, 3, 3}
    removeDup(&a)
    fmt.Println(a)
}

func removeDup(sp *[]int) {
    s := *sp
    n := len(s)
    tmp := make([]int, 0, n)
    tmp = append(tmp, s[0])
    for i := 1; i < n; i++ {
        if s[i] != s[i-1] {
            tmp = append(tmp, s[i])
        }
    }
    *sp = tmp
}
package main

import "fmt"

func main() {
    // returning a list
    a := []int{0, 1, 1, 3, 3, 3}
    clean := removeDup(a)
    fmt.Println(clean)
    // creating and using a named type
    nA := &newArrType{0, 1, 1, 3, 3, 3}
    nA.removeDup2()
    fmt.Println(nA)

    // or... casting your orginal array to the named type
    nB := newArrType(a)
    nB.removeDup2()
    fmt.Println(nB)
}

// using a set
// order is not kept, but a set is returned
func removeDup(s []int) (newArr []int) {
    set := make(map[int]struct{})
    for _, n := range s {
        set[n] = struct{}{}
    }
    newArr = make([]int, 0, len(set))
    for k := range set {
        newArr = append(newArr, k)
    }
    return
}

// using named a typed
type newArrType []int

func (a *newArrType) removeDup2() {
    x := *a
    for i := range x {
        f := i + 1
        if f < len(x) {
            if x[i] == x[f] {
                x = x[:f+copy(x[f:], x[f+1:])]
            }
        }
    }
    // check the last 2 indexes
    if x[len(x)-2] == x[len(x)-1] {
        x = x[:len(x)-1+copy(x[len(x)-1:], x[len(x)-1+1:])]
    }
    *a = x
}