動機

  1. promoted attr只是一種語法糖,不是繼承 (沒有subtype)
  2. promoted attr只是展開
  3. 把struct想成Let Over Lambda
  4. struct是value type
  5. interface就是看有沒有function
type a struct {}
type b struct {
  a
  string
}

b展開了a與string,但這不代表b是a的subtype!! 只是沒有name的欄位

所以a還是a,b還是b

但正如promoted attr,golang提供語法糖,promoted method,讓使用者以為有繼承

pointer type

type a struct {}

var x a
var y *a

x與y的type不同,如果是java或是python只有*a

method & interface

type a interface {
  f1()
}

type struct x {}

func (_ x) f1() {}

//var g *a
//g = &x{}
var g a
g = x{}
// g = &x{}

上面只有x有實作a,但是*x沒有!!

type a interface {
  f1()
}

type struct x {}

func (_ *x) f1() {}

var g a
g = &x{}

另外注意就算是物件指標,還是a,不是*a

template method pattern

type Iface {
  f1()
  f2()
}

type struct a {
  x int
}

type struct b {
  x float64
}

func (this *a) f1() {
  fmt.Println(this.x)
  this.f2()
}

func (this *a) f2() {
  fmt.Println(123)
}

func (this *b) f1() {
  this.f2()
  fmt.Println(this.x)
}

func (this *b) f2() {
  fmt.Println(234)
}

func template(f Iface, val int) {
  fmt.Println(val)
  f.f1()
  f.f2()
}

我google到的template method需要生struct,在裡面放實作iface的struct,十分繞

倒不如把struct當成lambda的第一層(let),之後的method當成大二層lambda

(define (a x)
  (lambda ()
    ...))