切片周围的包装纸正在做奇怪的事情

时间:2018-12-21 06:27:34

标签: go

我可能会浪费时间实施此操作,但是我正在寻找一种更轻松地将其推入/弹出的方法,所以我有这样的方法:

package h

import (
    "sync"
    log "github.com/sirupsen/logrus"
)

type List struct {
   internalList []interface{}
    mux sync.Mutex
}


func MakeList(l []interface{}) List{
    return List{l, sync.Mutex{}}
}


func (l List) Add(args ...interface{}) List{
    l.mux.Lock()
    l.internalList = append(l.internalList, args...)
    log.Info(l.internalList)
    l.mux.Unlock()
    return l;
}

func (l List) Push(v interface{}) List {
    l.mux.Lock()
    l.internalList = append(l.internalList, v)
    log.Info("internal:",l.internalList);
    l.mux.Unlock()
    return l;
}


func (l List) Pop() interface{}{
    l.mux.Lock()
    length :=len(l.internalList);
    log.Info("the length is:", length)
    if length < 1 {
        return nil;
    }
    last := l.internalList[length-1]
    l.internalList = l.internalList[:length-1]
    l.mux.Unlock()
    return last;
}

func (l List) GetLength() int {
    return len(l.internalList);
}

func (l List) Shift() interface{} {
    l.mux.Lock()
    if len(l.internalList) < 1 {
        return nil;
    }
    first := l.internalList[0];
    l.internalList = l.internalList[1:]
    l.mux.Unlock()
    return first;
}

func (l List) Unshift(v interface{}){
    l.mux.Lock()
    l.internalList = append([]interface{}{v}, l.internalList...)
    l.mux.Unlock()
}

func (l List) GetValue() []interface{}{
    return l.internalList
}

然后我像这样使用它:

package main

import (
    "github.com/sirupsen/logrus"
    "huru/h"
    "huru/utils"
)

func main(){

    x := h.List{}
    x.Push(3)
    logrus.Info("value:",x.GetValue())
    logrus.Info("len:",x.GetLength());
    logrus.Info(x.Pop());


}

但是奇怪的是我明白了:

INFO[0000] internal:[3]                                 
INFO[0000] value:[]                                     
INFO[0000] len:0                                        
INFO[0000] the length is:0                              
INFO[0000] <nil>        

我不知道为什么将3添加到切片中,但是切片长度神秘地变为零,当我pop()时得到零。有人知道为什么会这样吗?

鉴于现有答案,我想知道两者之间是否有区别

func (l *List) Add(args ...interface{}) *List {
    l.mux.Lock()
    l.internalList = append(l.internalList, args...)
    log.Info(l.internalList)
    l.mux.Unlock()
    return l;
}

func (l *List) Push(v interface{}) *List {
    l.mux.Lock()
    l.internalList = append(l.internalList, v)
    log.Info("internal:",l.internalList)
    l.mux.Unlock()
    return l
}

func (l *List) Add(args ...interface{}) List {
    l.mux.Lock()
    l.internalList = append(l.internalList, args...)
    log.Info(l.internalList)
    l.mux.Unlock()
    return *l;
}

func (l *List) Push(v interface{}) List {
    l.mux.Lock()
    l.internalList = append(l.internalList, v)
    log.Info("internal:",l.internalList)
    l.mux.Unlock()
    return *l
}

1 个答案:

答案 0 :(得分:5)

由于您的方法正在变异数据,因此它们需要使用指针接收器:

func (l *List) Push(v interface{}) List {
    ...
}

否则,状态将在结构的副本上更新,并在此之后丢失。

Effective Go

中的更多内容

更新:我注意到您从方法中返回更新后的值。如果您真正想要的是副本,则需要保持值接收者的状态不变,但是还要在调用代码中使用返回的值:

x = x.Push(3)