Golang 匿名结构体及测试代码编写技巧

转自: https://www.jianshu.com/p/901820e17ffb

结构体基础

结构体 (struct) 将多个不同类型的字段集中组成一种复合类型,按声明时的字段顺序初始化。
type user struct {
  name string
  age byte
}

user := user {"Tom", 2}

定义匿名结构体时没有 type 关键字,与其他定义类型的变量一样,如果在函数外部需在结构体变量前加上 var 关键字,在函数内部可省略 var 关键字。
// 在函数外部定义匿名结构体并赋值给 config
var config struct {
  APIKey string
  OAuthConfig oauth.Config
}

// 定义并初始化并赋值给 data
data := struct {
  Title string
  Users []*User
}{
  title,
  users
}

匿名结构体在四种常见情景下的用法。

组织全局变量

属于同一类的全局变量可通过匿名结构体组织在一起。

var config struct {
    APIKey      string
    OAuthConfig oauth.Config
}

config.APIKey = "BADC0C0A"

数据模版

可在后端把数据组织成前端需要的格式传给渲染模版
package main

import (
    "html/template"
    "net/http"
    "strings"
)

type Paste struct {
    Expiration string
    Content    []byte
    UUID       string
}

func pasteHandler(w http.ResponseWriter, r *http.Request) {
    paste_id := strings.TrimPrefix(r.URL.Path, "/paste")
    paste := &Paste{UUID: paste_id}
    keep_alive := false
    burn_after_reading := false

    data := struct {
        Paste *Paste
        KeepAlive bool
        BurnAfterReading bool
    } {
        paste,
        keep_alive,
        burn_after_reading,
    }
    t, _ := template.ParseFiles("templates/paste.html")
    t.Execute(w, data)
}

匿名函授定义并初始化之后赋值给 data 变量,除了把 Paste 结构体对象的值传给前端之外,还额外添加了必要的字段。
写过前后端的同学应该知道,前端有时需要后端返回一个标志变量作为判断条件是否显示某一块内容。
Expiration: {{ .Paste.Expiration }}
UUID: {{ .Paste.UUID}}
{{ if .BurnAfterReading }}
BurnAfterReading: True
{{ else }}
BurnAfterReading: False
{{ end }}

测试案例数据

在写测试代码时,经常用到匿名结构体生成用例的输入输出,为了覆盖各个测试维度,通常结合切片使用,构成了测试样例尽可能地覆盖所有可能发生情况。
var indexRuneTests = []struct {
    s    string
    rune rune
    out  int
}{
    {"a A x", 'A', 2},
    {"some_text=some_value", '=', 9},
    {"☺a", 'a', 3},
    {"a☻☺b", '☺', 4},
}

嵌入式锁 (Embedded lock)

var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()
posted @ 2019-07-22 16:35  xushukui  阅读(642)  评论(0编辑  收藏  举报