【go】《Go语言编程》第三章完整示例问题

最近在学习Go语言,看的书是《Go语言编程》许式伟 七牛团队的。我基本会把书上的例子都会练习一遍,当是一种学习方法。当然也会遇到一点问题,没事可以骚扰下许式伟。

先补充下第二章中的疑问(应sf的要求在这里面进行提问)

第二章中的完整事例其中有一段:

for{

line,isPrefix,err1 := br.ReadLine()

if err1 != nil {

if err1 != io.EOF{

err = err1

}

break

}

if isPrefix{

fmt.Println( "A too long line,seems unexpectd." )

return

}

str := string( line )

value,err1:=strconv.Atoi( str )

if err1 != nil{

err = err1

return

}

values = append( values,value )

}

下面这段代码开始看的时候 觉得err1相关的代码非常多余,因为都会返回err,当然我想当然了。如果不使用新的变量会报如下的错误

err1 ./sorter.go:37: err is shadowed during return

@许式伟 帮我解答了 “意思是里层的err把外层的err屏蔽了。”

=================================================================================

现在第三章的完整示例代码,我已经测试了,发现如下几个问题:

PS:有此应该是作者预留的,有些不知道是不是笔误,所以请 @许式伟 查看下

  1. manager.go一开始的 musics []MusicEntry 这个struct名字和上文中的不一样
  2. 并没有提供WAVPlayer{}当然这个得自己写 应该是预留的 只是做了一个mp3的示例
  3. 在manager_test.go 最后一个 t.Error( "MusicManager.Remove() failed.",err ) 应该是没有err的
  4. 主程序中remove <name> 使用的是RemoveByName 并没有这个方法 ,我将方法Find和Remove结合写了一个RemoveByName,但是Remove是index并不是id,这里我还没有调试,我觉得可能按id删除会比较好。
  5. 在主程序播放位置mp.Play(e.Source,e.Type,ctrl,signal) 应该是作者预留了两个ctrl控制和signal信号。
  6. 在主程序lib add 的时候id++ 应该放置在lib.Add之后,这样第一个添加的才是id为1不然就成了2了

总体来说这个示例是不完全可用的,但作者在最后演示的时候是正常的,我不知道是印刷的问题还是故意这样编排的。

================================================================

再补充两个问题:

  1. 上次忘说了在这段示例里面有几个地方用了elseif go应该不支持这样写吧
  2. 另外在Remove方法里面,应该是有逻辑问题的,会报out of range的问题。我按原来的思路修改如下:

func ( m *MusicManager)Remove( index int ) *MusicEntry {

if index <0 || index >= len( m.musics ){

return nil

}

removeMusic := &m.musics[index]

if index == 0 {

m.musics = m.musics[index+1:]

} else if index == len( m.musics)-1 {

m.musics = m.musics[:index]

}else {

m.musics = append( m.musics[:index],m.musics[index+1:]... )

}

return removeMusic

}

如果不用slice切片的方法,应该有更简洁的办法来删除range的index吧。

回答

楼主看得真认真,赞一个。这部分样例是我写的,因此就我来回答一下吧。

在构思这个样例时,我换过好几次想法。一开始准备写一个相对完整的播放器框架,但在写了一部分后发现这样的话会占用太多的书本空间,有凑页数之嫌,因此进行了大幅度的精简。这个精简过程导致了文字和代码的不一致,更杯具的是在审阅的时候又没发现。代码和文档一致性维护的难度也就是doxygen这类工具比较流行的一大原因。

1. 这是代码调整后遗留的问题,初步的想法是做Media Player,但那样层次会更多看起来更累。毕竟这本书的重点是语法而不是设计。

2. 这个相信你也看懂了,就不重复写一遍了。

3. 确实没必要,是拷贝代码的问题。杯具的是,编译和运行测试都没有暴露这个问题。

4. RemoveByName方法的实现如下。作为命令行,我们不能指望用户在本子上记住id,因此必须的用name。

func (m *MusicManager) RemoveByName(name string) *MusicEntry {

if len(m.musics) == 0 {

return nil

}

for i, v := range m.musics {

if v.Name == name {

return m.Remove(i)

}

}

return nil

}

5. ctrl和signal这两个channel的设计目的是可以留在那里作为未完成的功能,比如音乐播放过程中的控制(比如暂停),以及播放过程中的消息发送等。这个继续下去也超过了语法演示的目的。

6. id本身只需要保证唯一性,并不假设第一个必须为1,因此前后其实都没有大的区别。

总之,我本人为这些不够严谨的地方向读者致歉。我们在重印时会把所有收集到的问题全部修改,避免浪费大家的脑细胞。

鄙人觉得remove函数这样写会更好一些
m.musics = append(m.musics[:index], m.musics[index+1:]...)

同样是这个例子,还有一个问题,我发到这儿:http://segmentfault.com/q/10100000001...

麻烦帮我看看吧~~ @吕桂华 多谢了

您好,有个问题想咨询一下,我在运行第二章完整示例的时候遇到了一个问题

【go】《Go语言编程》第三章完整示例问题

strconv.Atoi: parsing "": invalid syntax
就是这个错误是怎么出现的呢。前面str可以打印出来,是有值的。
如果有时间请指导一下,谢谢

以上是 【go】《Go语言编程》第三章完整示例问题 的全部内容, 来源链接: utcz.com/a/98776.html

回到顶部