List 的逗号分隔打印

· Chen Pan

今天在浏览大佬们的博客时,发现 matklad 在他的博客 Printing Lists 中介绍了一种很简洁的、以逗号分隔打印 list 的写法。在此之前,我从来没有想到还可以这样处理。

从最终的输出结果来看,逗号总是出现在两个元素之间,所以我以前的第一反应一直是:先打印当前元素,然后 再决定是否打印逗号。这样一来,就需要额外判断当前元素是不是 list 的最后一个元素,以避免在末尾多打印 一个逗号。

以前我通常会写成这样:

 1l := list.New()
 2
 3for i := 0; i < 10; i++ {
 4	l.PushBack(i)
 5}
 6
 7for e := l.Front(); e != nil; e = e.Next() {
 8	fmt.Print(e.Value)
 9	if next := e.Next(); next != nil {
10		fmt.Print(", ")
11	}
12}

matklad 的思路恰好反过来了:不去判断当前元素是不是最后一个,而是判断当前元素是不是第一个。 即先打印分隔符,再打印元素,所以是这样的:

 1l := list.New()
 2
 3for i := 0; i < 10; i++ {
 4	l.PushBack(i)
 5}
 6
 7for e := l.Front(); e != nil; e = e.Next() {
 8  	if e != l.Front() {
 9      	fmt.Print(", ")
10  	}
11  	fmt.Print(e.Value)
12}

两种方式的区别并不在于谁能实现这个功能,而在于观察问题的角度不同。第一种方式 关注“当前元素之后是否还有内容”,因此需要判断结束状态;而第二种方式关注“当前 元素之前是否已经存在内容”,只需要维护已经发生的状态。对于大多数迭代场景来说, 后者通常更加自然,因为迭代器更擅长描述过去,而不是预测未来。