This repository has been archived by the owner on Nov 2, 2018. It is now read-only.
/
var.go
48 lines (45 loc) · 1.47 KB
/
var.go
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
package build
import "reflect"
// A Var represents a variable whose value depends on which Release is being
// compiled. None of the fields may be nil, and all fields must have the same
// type.
type Var struct {
Standard interface{}
Dev interface{}
Testing interface{}
// prevent unkeyed literals
_ struct{}
}
// Select returns the field of v that corresponds to the current Release.
//
// Since the caller typically makes a type assertion on the result, it is
// important to point out that type assertions are stricter than conversions.
// Specifically, you cannot write:
//
// type myint int
// Select(Var{0, 0, 0}).(myint)
//
// Because 0 will be interpreted as an int, which is not assignable to myint.
// Instead, you must explicitly cast each field in the Var, or cast the return
// value of Select after the type assertion. The former is preferred.
func Select(v Var) interface{} {
if v.Standard == nil || v.Dev == nil || v.Testing == nil {
panic("nil value in build variable")
}
st, dt, tt := reflect.TypeOf(v.Standard), reflect.TypeOf(v.Dev), reflect.TypeOf(v.Testing)
if !dt.AssignableTo(st) || !tt.AssignableTo(st) {
// NOTE: we use AssignableTo instead of the more lenient ConvertibleTo
// because type assertions require the former.
panic("build variables must have a single type")
}
switch Release {
case "standard":
return v.Standard
case "dev":
return v.Dev
case "testing":
return v.Testing
default:
panic("unrecognized Release: " + Release)
}
}