golang官⽅指南-练习案例
练习:切⽚实现 Pic。
它应当返回⼀个长度为 dy 的切⽚,其中每个元素是⼀个长度为 dx,元素类型为 uint8 的切⽚。当你运⾏此程序时,它会将每个整数解释为灰度值(好吧,其实是蓝度值)并显⽰它所对应的图像。图像的选择由你来定。⼏个有趣的函数包括 (x+y)/2, x y, x^y, x log(y) 和 x%(y+1)。(提⽰:需要使⽤循环来分配 [][]uint8 中的每个 []uint8;请使
⽤ uint8(intValue) 在类型之间转换;你可能会⽤到 math 包中的函数。)
这⾥刚开始准备直接进⾏键值赋值然后输出的,结果发现,切⽚⽆法和python的数组⼀样进⾏直接赋值,⼀般做法是通过append来赋值
package main
import "/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
pic := [][]uint8{}
for i:=0 ; i < dx ; i++{
row := []uint8{}
for m:=0; m <dy ; m++{
row = append(row,uint8(dx & dy))
}
pic = append(pic,row)
}
return pic
}
func main() {
pic.Show(Pic)
}
练习:映射实现 WordCount。
它应当返回⼀个映射,其中包含字符串 s 中每个“单词”的个数。函数 wc.Test 会对此函数执⾏⼀系列测试⽤例,并输出成功还是失败。你会发现 strings.Fields 很有帮助。
这个题⽬理解了半天,才知道应该是wc.Test会不停使⽤不同参数调⽤WordCount,然后输出验证的结果,这次没有参考答案,⼿写出来的,遇见的问题⽐较多,第⼀次是使⽤for 循环通过i去遍历map,没有使⽤range,想直接⽤map[i]的形式取值赋值,导致各种报错,后来发现案例基本上都是使⽤range去遍历map,改写为for range以后,问题解决,然后统计重复值个数就以if来判断是否对应单词的key已存在,如果已存在代表已经在第⼀次统计这个单词时初始化为1了,那么第⼆次统计到这个单词的时候直接⾃增就可以了,如果不存在代表是第⼀次遇见这个单词,直接初始化为1就可以
package main
import (
"/x/tour/wc"
"strings"
)
func WordCount(s string) map[string]int{
Result := make(map[string]int)
for _,value := range(strings.Fields(s)){
_, ok := Result[value]
if ok == true {
Result[value]++
}else{
Result[value]=1
}
}
return Result
}
func main() {
wc.Test(WordCount)
}
最终通过测试的结果如下:
练习:Stringer
通过让 IPAddr 类型实现 fmt.Stringer 来打印点号分隔的地址。例如,IPAddr{1, 2, 3, 4} 应当打印为 "1.2.3.4"。
package main
import "fmt"
type IPAddr [4]byte
// TODO: 给 IPAddr 添加⼀个 "String() string" ⽅法
func (ip IPAddr) String() string {
return fmt.Sprintf("%v.%v.%v.%v", ip[0],ip[1],ip[2],ip[3])
}
func main() {
hosts := map[string]IPAddr{
"loopback": {127, 0, 0, 1},
"googleDNS": {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip)
}
}
最终结果如下:
练习:错误
package main
import (
go 字符串转数组"fmt"
"math"
)
// 定义类型
type ErrNegativeSqrt float64
// 重写Error()
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
func Sqrt(x float64) (float64, error) {
if x < 0 {
return 0, ErrNegativeSqrt(x)
}
return math.Sqrt(x), nil
}
func main() {
//通常函数会返回⼀个 error 值,调⽤的它的代码应当判断这个错误是否等于 nil,来进⾏错误处理。
//这⾥只是简单的打印
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
通过调试可以知道,如果Sprintf后⾯不对e进⾏强转,会将e当作错误类型,然后调⽤e.Error()⽅法,⽽e.Error()⼜被我们定义了⼀个⾥⾯包含Sprintf的error⽅法,导致不停地就是Sprintf调⽤e.error然后e.error调⽤sprintf,造成递归
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论