[日常] 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)
        }
}

  

posted @   唯一客服系统开发笔记  阅读(362)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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
点击右上角即可分享
微信分享提示
1
chat with us