围棋又把我难倒了。希望有人能帮上忙。我已经创建了一个切片(mySlice),其中包含指向结构(myStruct)的指针。
问题在于"Remove“方法。当我们在"Remove“里面时,一切都很好,但是一旦我们返回,切片的大小并没有改变,所以我们看到最后一个元素列出了两次。
我最初尝试使用"Add“方法中使用的相同模式编写"Remove”,但它无法编译,因此被注释掉了。
我可以通过将新创建的切片返回给调用函数来让它工作,但我不想这样做,因为mySlice (ms)是一个单例。
如果我问的还不够多的话...
"Add“方法的代码正在工作,尽管我不确定是如何工作的。据我所知,"Add“是接收一个指向切片标题(3项"struct")的指针。据我所知,切片的长度和容量不会传递给方法(当通过值传递时),所以可能传递一个指向切片的指针可以让方法看到并使用长度和容量,从而允许我们“追加”。如果这是真的,那么为什么同样的模式在“删除”中不起作用呢?
非常感谢大家的见解和帮助!
package main
import (
"fmt"
)
type myStruct struct {
a int
}
type mySlice []*myStruct
func (slc *mySlice) Add(str *myStruct) {
*slc = append(*slc, str)
}
//does not compile with reason: cannot slice slc (type *mySlice)
//func (slc *mySlice) Remove1(item int) {
// *slc = append(*slc[:item], *slc[item+1:]...)
//}
func (slc mySlice) Remove(item int) {
slc = append(slc[:item], slc[item+1:]...)
fmt.Printf("Inside Remove = %s\n", slc)
}
func main() {
ms := make(mySlice, 0)
ms.Add(&myStruct{0})
ms.Add(&myStruct{1})
ms.Add(&myStruct{2})
fmt.Printf("Before Remove: Len=%d, Cap=%d, Data=%s\n", len(ms), cap(ms), ms)
ms.Remove(1) //remove element 1 (which also has a value of 1)
fmt.Printf("After Remove: Len=%d, Cap=%d, Data=%s\n", len(ms), cap(ms), ms)
}结果..。
Before Remove: Len=3, Cap=4, Data=[%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{1}) %!s(*main.myStruct=&{2})]
Inside Remove = [%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{2})]
After Remove: Len=3, Cap=4, Data=[%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{2}) %!s(*main.myStruct=&{2})]发布于 2013-09-02 14:07:19
第一次使用Remove1()时你是对的。Remove获取切片的副本,因此无法更改切片的长度。
remove函数中的问题是,根据Go中的操作顺序,切片在取消引用之前进行。
修复方法是将*slc = append(*slc[:item], *slc[item+1:]...)更改为*slc = append((*slc)[:item], (*slc)[item+1:]...)。
然而,为了提高可读性和可维护性,我建议使用以下代码:
func (slc *mySlice) Remove1(item int) {
s := *slc
s = append(s[:item], s[item+1:]...)
*slc = s
}发布于 2014-02-22 23:32:51
因为正如Stephen Weinberg所指出的,追加不一定会返回与切片相同的引用地址。解决此限制的另一种方法是定义包装切片的结构。
例如:
package main
import "fmt"
type IntList struct {
intlist []int
}
func (il *IntList) Pop() {
if len(il.intlist) == 0 { return }
il.intlist = il.intlist[:len(il.intlist)-1]
}
func (il *IntList) Add(i... int) {
il.intlist = append(il.intlist, i...)
}
func (il *IntList) String() string {
return fmt.Sprintf("%#v",il.intlist)
}
func main() {
intlist := &IntList{[]int{1,2,3}}
fmt.Println(intlist)
intlist.Pop()
fmt.Println(intlist)
intlist.Add([]int{4,5,6}...)
fmt.Println(intlist)
}输出:
[]int{1, 2, 3}
[]int{1, 2}
[]int{1, 2, 4, 5, 6}https://stackoverflow.com/questions/18566499
复制相似问题