[日常] Go语言圣经-可变参数习题
2023-02-18 15:41:37 时间
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")
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) } }
相关文章
- USB总线-Linux内核USB3.0设备控制器驱动框架分析(四)
- Linux Regulator Framework(1)_概述
- MongoDB安全加固,防止数据库攻击删除勒索威胁
- vcftools教程1:Linux系统中安装vcftools
- BLUP is a good thing!
- 全志D1-H Tina Linux LEDC开发指南
- C++类和对象(上)
- Golang环境初始化
- 【Django】在大型项目中的django的性能模型字段primary_key
- 【Django】QuerySet以及Pickle 序列化在Django中的深度运用详解
- 【Django】当大型项目采用Django框架对于QueryDict以及模板的表单在Admin 管理工具的使用
- 【Django】聚合在Django的详细解析以及运用在企业级项目里的方法
- Django管理应用程序的高级配置在BookInstance模型的运用【Django】
- 对于Django框架的会话框架的深入研究——在大型项目中使用会话技术【Django】
- centos7安装php7
- Linux CentOS 7下启动、关闭、重启、查看MySQL服务
- phpMyAdmin错误提示解决
- 云原生应用Go语言:你还在考虑的时候,别人已经应用实践
- C++调用Go方法的字符串传递问题及解决方案
- 【云小课】版本管理发展史之Git+——代码托管