工作中用 go 设计了一个 stack 的数据结构
type Stack struct {
items []int
}
func (s *Stack) IsEmpty() bool {
return len(s.items) == 0
}
func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}
func (s *Stack) Pop() (int, error) {
if s.IsEmpty() {
return 0, errors.New("pop from empty stack")
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item, nil
}
func xx() {
s := Stack{}
// 往栈中 push 一些元素
s.Push(1)
for !s.IsEmpty() {
v, err := s.Pop()
if err != nil {
break
}
// do something
fmt.Println(v)
}
}
现在的问题就是这个 if err != nil {} 这一段代码在这里真的太丑了(我的函数其实是纯数据的处理,本来还是简单优雅的,加上这个 error 觉得代码变丑了),并且我的代码逻辑已经判断了 栈 不为空,里面的 err 判断其实根本没有必要,当然 go 可以强制忽略这个错误。但是,还是丑,并且强制忽略错误不严谨,看着别扭。
func xx() {
s := Stack{}
// 往栈中 push 一些元素
s.Push(1)
for !s.IsEmpty() {
v, _ := s.Pop()
// do something
fmt.Println(v)
}
}
最后我实在看不下去这种代码,直接用了 slice 。
func x2() {
var s []int
s = append(s, 1)
for len(s) != 0 {
v := s[len(s)-1]
// do something
fmt.Println(v)
s = s[:len(s)-1]
}
}
在我看来,go 的 error 如果用在业务逻辑里面,写 if err != nil {} 这种代码,我觉得没啥问题。但是在设计数据结构的时候,如果用到 error 确实很别扭,并且你还要 import errors 这个包。
我看了一下 go 的 sdk 里面一些数据结构的设计,比如 container/heap 堆的设计,它直接不判断 h.Len() 是否为 0 。这样倒是没有我说的那个 error 代码丑的问题,但是这样更不严谨了。
// Pop removes and returns the minimum element (according to Less) from the heap.
// The complexity is O(log n) where n = h.Len().
// Pop is equivalent to Remove(h, 0).
func Pop(h Interface) interface{} {
n := h.Len() - 1
h.Swap(0, n)
down(h, 0, n)
return h.Pop()
}
如果我用 python 或者 java 这种带有异常的语言去写数据结构。
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return len(self.items) == 0
def push(self, item):
self.items.append(item)
def pop(self):
if self.is_empty():
raise IndexError("pop from empty stack")
return self.items.pop()
if __name__ == "__main__":
stack = Stack()
stack.push(1)
while not stack.is_empty():
v = stack.pop()
# do something
print(v)
这样我觉得好看多了。
还是不喜欢 go 一些大道至简的设计。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.