[日常] Go语言圣经-可变参数习题
1.参数数量可变的函数称为为可变参数函数,例子就是fmt.Printf和类似函数
2.参数列表的最后一个参数类型之前加上省略符号“...”
3.虽然在可变参数函数内部,...int 型参数的行为看起来很像切片类型,但实际上,可变参数函数和以切片作为参数的函数是不同的
类型不同:fmt.Printf("%T\n", f)
4.函数名的后缀f是一种通用的命名规范,代表该可变参数函数可以接收Printf风格的格式化字符串
5.interfac{}表示函数的最后一个参数可以接收任意类型
练习5.15: 编写类似sum的可变参数函数max和min。考虑不传参时,max和min该如何处理,再编写至少接收1个参数的版本。
练习5.16:编写多参数版本的strings.Join。
练习5.17:编写多参数版本的ElementsByTagName,函数接收一个HTML结点树以及任意数量的标签名,返回与这些标签名匹配的所有元素。下面给出了2个例子:
func ElementsByTagName(doc *html.Node, name...string) []*html.Node
images := ElementsByTagName(doc, "img")
headings := ElementsByTagName(doc, "h1", "h2", "h3", "h4")
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package main import ( "fmt" "golang.org/x/net/html" "net/http" ) func main() { fmt.Println(max(1, 2, 3, 4, 2)) fmt.Println(max()) fmt.Println(join( "-" , "hello" , "tsh" , "hi" )) resp, _ := http.Get( "http://mail.sina.net" ) doc, _ := html.Parse(resp.Body) resp.Body.Close() tNodes := ElementsByTagName(doc, "p" , "a" ) for _, v := range tNodes { ForEachNode(v) fmt.Println( "------------------------" ) } } /* 练习5.15: 编写类似sum的可变参数函数max和min。考虑不传参时,max和min该如何处理,再编写至少接收1个参数的版本。 */ func max(vals ...int) (int, error) { var m int num := len(vals) if num == 0 { return 0, fmt.Errorf( "max: %s" , "至少传递一个参数" ) } for _, v := range vals { if m < v { m = v } } return m, nil } /* 练习5.16:编写多参数版本的strings.Join。 */ func join(sep string, strs ...string) (string, error) { var res string var num = len(strs) if num == 0 { return "" , fmt.Errorf( "join: %s" , "至少传递一个参数" ) } for i, v := range strs { if i == (num - 1) { res += v } else { res += v + sep } } return res, nil } /* 练习5.17:编写多参数版本的ElementsByTagName,函数接收一个HTML结点树以及任意数量的标签名,返回与这些标签名匹配的所有元素。下面给出了2个例子: */ var nodes []*html.Node func ElementsByTagName(n *html.Node, names ...string) []*html.Node { newNode := n for _, name := range names { if n.Type == html.ElementNode && n.Data == name { nodes = append(nodes, newNode) } } for c := n.FirstChild; c != nil; c = c.NextSibling { //可变参数传参特点 ElementsByTagName(c, names...) } return nodes } func ForEachNode(n *html.Node) { fmt.Println(n.Data) for c := n.FirstChild; c != nil; c = c.NextSibling { ForEachNode(c) } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2016-04-18 [android] 用fragment创建一个选项卡
2016-04-18 [android] fragment的动态创建
2016-04-18 [Python] 函数基本
2016-04-18 [Python] 使用dict和set