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)
}
}

  

[日常] Go语言圣经-可变参数习题的更多相关文章

  1. [日常] Go语言圣经--接口约定习题

    Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...

  2. [日常] Go语言圣经-匿名函数习题

    Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...

  3. [日常] Go语言圣经-错误,函数值习题

    Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...

  4. [日常] Go语言圣经-Slice切片习题

    1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型:slice的语法和数组很像,只是没有固定长度而已,slice的底 ...

  5. [日常] Go语言圣经-竞争条件习题

    package main import( "fmt" "sync" ) var balance int func Deposit(amount int) { b ...

  6. [日常] Go语言圣经--接口约定习题2

    练习 7.3: 为在gopl.io/ch4/treesort (§4.4)的*tree类型实现一个String方法去展示tree类型的值序列. package main import( "f ...

  7. [日常] Go语言圣经-匿名函数习题2

    练习5.13: 修改crawl,使其能保存发现的页面,必要时,可以创建目录来保存这些页面.只保存来自原始域名下的页面.假设初始页面在golang.org下,就不 要保存vimeo.com下的页面. p ...

  8. [日常] Go语言圣经-函数递归习题

    练习 5.1: 修改findlinks代码中遍历n.FirstChild链表的部分,将循环调用visit,改成递归调用. 练习 5.2: 编写函数,记录在HTML树中出现的同名元素的次数. 练习 5. ...

  9. C语言的可变参数在Linux(Ubuntu)与Windows下注意点

    基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...

随机推荐

  1. docker容器中的peewee如何连接已有的容器中的数据库

    首先,两个容器必须是在同一网络下,有2个办法. 一个是在同一个docker-compose.yml文件下使用links参数,比如: version: '3' services: redis: imag ...

  2. 介绍 Scratch 3.0:扩展编码创造力

    在过去十年中,全世界数百万儿童使用Scratch编写自己的互动游戏,故事,动画等. 这种磅礴的创造力激励我们继续扩展和改进Scratch,让世界各地的孩子都有新的机会用新技术创造性地表达自己. 今天, ...

  3. 【洛谷4238】 多项式求逆(NTT,分治)

    前言 多项式求逆还是爽的一批 Solution 考虑分治求解这个问题. 直接每一次NTT一下就好了. 代码实现 #include<stdio.h> #include<stdlib.h ...

  4. [NOIP2018]保卫王国(树形dp+倍增)

    我的倍增解法吊打动态 \(dp\) 全局平衡二叉树没学过 先讲 \(NOIP\) 范围内的倍增解法. 我们先考虑只有一个点取/不取怎么做. \(f[x][0/1]\) 表示取/不取 \(x\) 后,\ ...

  5. python项目实现配置统一管理的方法

    一个比较大的项目总是会涉及到很多的参数,最好的方法就是在一个地方统一管理这些参数.最近看了不少的python项目,总结了两种很有意思的配置管理方法. 第一种 基于easydict实现的配置管理 首先需 ...

  6. Spring中ioc的实现原理

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  7. Smart/400开发上手1:入门

    1.介绍 Smart/400是在AS/400之上的开发平台,管理开发.运维的全生命周期. 2.设计基础 Introducing Fields Smart通过字段字典Field Dictionary来存 ...

  8. abp 使用 hangfire结合mysql

    abp 官方使用的hangfire 默认使用的是sqlserver的存储 需要引入支持mysql的类库 我这边使用的是Hangfire.MySql.Core 直接用nuget安装即可 首先按照官方文档 ...

  9. java 简单认识移位运算符和位运算符

    移位运算符和位运算符本质上都是操作二进制位,因为计算机存储的是二进制数据,运算效率相对较高. 移位运算符:把整数的二进制位进行左移或右移 .左移一位,相当于这个数乘以2, 右移一位,相当于这个数除以2 ...

  10. babel 7 简单指北

    babel 7 对于 babel 7,babel 的官网已经介绍得非常详细了,但有时感觉文档和实际使用总是差那么一点东西. 主要包 先来看一下主要的包,babel 7 对于包进行了一些简化. @bab ...