**### JSON
golang通过标准库encoding/json,encoding/xml,encoding/asn1以及其他库对这些格式的编码和解码提供了非常好的支持,这些库都拥有相同的API。JSON是JavaScript值的Unicode编码,这些值包括字符串、数字、布尔值、数组和对象。
JSON最基本的类型是数字(以十进制或者科学计数法表示)、布尔值(true或false)和字符串(用双引号括起来的)。JSON的数组是一个有序的元素序列,每个元素之间用逗号分隔,两边使用方括号括起来。JSON的对象是一个从字符串到值的映射,写成name:value对的序列,每个元素之间用逗号分隔,两边使用花括号括起来。- 把Go的数据结构转换为
JSON成为marshal。marshal通过json/Marshal实现。
data, err := json.Marshal(valueType)
if err != nil {
log.Fatalf("JSON marshaling failed: %s", err)
}
json.MarshalIndent的变体可以输出整齐格式化过的结果。
data, err := json.MarshalIndent(valueType, "", " ") // 一个定义每行输出的前缀字符串,另外一个定义缩进的字符串。
marshal使用Go结构体成员的名称作为JSON对象里面字段的名称。只有可导出的成员可以转换为JSON字段。marshal的逆操作将JSON字符串解码为Go数据结构,这个过程叫做unmarshal,这个是由json.Unmarshal实现的。通过合理地定义Go的数据结构,可以选择将哪部分JSON数据解码到结构体对象中,哪些数据可以丢弃。
文本和HTML模板
text/template和html/template两个包可以实现格式和代码彻底分离,这里提供了一种机制,可以将程序变量的值带入到文本或者HTML模板中。
- 模板是一个字符串或者文件,它包含一个或者多个两边用双大括号包围的单元
{{...}},这称为操作。操作可以引发其他行为。 - 每个操作都对应一个表达式,提供输出值,选择结构体成员,调用函数和方法,描述控制逻辑,实例化其他模板等功能。
- 在操作中,符号
|会将前一个操作的结果当作下一个操作的输入。 - 在操作中,用点号
.表示当前值的标记。
模板输出结果需要两个步骤。
- 首先需要解析模板并转换为内部的表示方法。
- 然后在指定的输入上面执行。解析模板只需要执行一次。
report, err := template.New("report").Funcs(template.FuncMap{}).Parse(templ)
if err != nil {
log.Fatal(err)
}
- 模板通常是在编译期间就固定下来,因此无法解析模板将是程序程序中的一个严重
bug。帮助函数template.Must提供了一种便捷的错误处理方式,它接受一个模板和错误作为参数,检查错误是否为nil(如果不是nil,则宕机),然后返回这个模板。
report := template.Must("report").Funcs(template.FuncMap{}).Parse(templ)
函数
函数声明
每个函数声明都包含一个名字、一个形参列表、一个可选的返回列表以及函数体。
func name(parameter-list) (result-list) {
body
}
- 如果一个函数既省略返回列表也没有任何返回值,那么设计这个函数的目的是调用函数之后所带来的附加效果。
- 空白标识符用来强调这个形参在函数中未使用。
- 函数的类型称作函数签名,当两个函数拥有相同的形参列表和返回列表是,认为这两个函数的类型或签名是相同的。
golang没有默认参数值的概念也不能指定实参名。- 实参都是按值传递,所以函数接收到的是每个实参的副本。
- 如果提供的实参包含引用类型,比如指针、
slice、map、函数或者通道,那么当函数使用形参变量时就有可能会间接地修改实参变量。
递归
函数可以递归调用,这一位置函数可以直接或间接地调用自己。
- 许多编程语言使用固定长度的函数调用栈;大小在
64KB到2MB之间。 - 递归的深度会受限于固定长度的栈大小,所以当进行深度递归调用时必须谨防栈溢出。
golang语言的实现使用了可变长度的栈,栈的大小会随着使用而增长,可达到1GB左右的上限。**