type A = B 只相当于别名, 多用于兼容

type A B 想象人在不同场合下的不同角色,在家是好丈夫,在公司是好同事,但在家和在公司做的事情不一样, typeA 和 typeB 的方法不能相互使用,可用于扩展定义自己的方法

// Convert string to specify type.
type StrTo string

func (f StrTo) Exist() bool {
	return string(f) != string(0x1E)
}

func (f StrTo) Uint8() (uint8, error) {
	v, err := strconv.ParseUint(f.String(), 10, 8)
	return uint8(v), err
}

page, _ := com.StrTo(c.Query("page")).Int()

type A func() returnType

type Operator func(x float64) float64

// Map applies op to each element of a.
func Map(op Operator, a []float64) []float64 {
    res := make([]float64, len(a))
    for i, x := range a {
        res[i] = op(x)
    }
    return res
}

func main() {
    op := math.Abs
    a := []float64{1, -2}
    b := Map(op, a)
    fmt.Println(b) // [1 2]

    c := Map(func(x float64) float64 { return 10 * x }, b)
    fmt.Println(c) // [10, 20]
}

Type conversions

i := 42
f := float64(i)
u := uint(f)

类型转换类型断言本质都是把一个类型转换成另外一个类型。不同之处在于,类型断言是对接口变量进行的操作

对于 类型转换 转换前后两个类型要相互兼容

var i int = 9
var f float64
f = float64(i)
fmt.Printf("%T, %v", f, f) // float64, 9

f = 10.8
a := int(f)
fmt.Printf("%T, %v", a, a) // int, 10

s := []int(i) // cannot convert i (type int) to type []int

interface{} 没有定义任何函数,因此 Go 所有类型都实现了空接口,当一个函数的行参是 interface{} 那么需要对其进行断言,从而得知真实类型

Type Assertion

x.(T)
// x 是一个接口类型的表达式, T 是一个类型
// x.(T) asserts that x is not nil and that the value stored in x is of type T.

Imagine you need to calculate area of 4 different shapes: Circle, Square, Rectangle and Triangle. You may define new types with a new method called Area() like this:

type Circle struct {
    Radius float64
}
func (t Circle) Area() float64 {
    return math.Pi * t.Radius * t.Radius
}

And for Triangle, Rectangle, Square

type Triangle struct {
    A, B, C float64 // lengths of the sides of a triangle.
}
func (t Triangle) Area() float64 {
    p := (t.A + t.B + t.C) / 2.0 // perimeter half
    return math.Sqrt(p * (p - t.A) * (p - t.B) * (p - t.C))
}

type Rectangle struct {
    A, B float64
}

func (t Rectangle) Area() float64 {
    return t.A * t.B
}

type Square struct {
    A float64
}
func (t Square) Area() float64 {
    return t.A * t.A
}

Now we want to collect them all in one place, First we need Shape interface to collect them all in one slice of shape []Shape