Skip to content

《go与js的类型系统的异同比较》小记 #5

@Cyberhan123

Description

@Cyberhan123

go 的struct的与c相同所以如果要通过面向对象来实现 继承必然会有问题
而go中的interface 相较而言却十分方便实现

从JS babel-parser的代码到go parse可以看出

babel的代码完全面向对象
而go的代码其实是面向接口,所以我觉得应该吸收他们的优点后进行改造

现在解析的ast的逻辑我是参照babel实现的,因而就会发现,其实很多estree 在go的表达应该是interface{}

所以通过理解我们可以得出

go 的面向对象与js || java 而言是分离的

go 的interface 意味着:
单独声明super abs ... 等等class 到 interface
至于具体实物则为struct 而struct 则尽量不应该继承,而是通过struct 去实现 interface 从而达到泛型的目的

而至于1.18的泛型是否能简化每个struct的使用是可以后续考虑的
下面我写点带go味的代码

type Food interface {
	Tasty()
}

type Beef struct {
// Beef attr
}

func (b Beef) Tasty() {}

type Grass struct {
// Grass attr
}

func (g Grass) Tasty() {}

type Animal interface {
	Eat(f Food) bool
}

type Dog struct {
// Dog   attr
}

func (d Dog) Eat(f Food) bool {
	f.Tasty()
	switch f.(type) {
	case Grass:
		return false
	case Beef:
		return true
	default:
		return false
	}
}

type Rabbit struct {
}

func (d Rabbit) Eat(f Food) bool {
	f.Tasty()
	switch f.(type) {
	case Grass:
		return true
	case Beef:
		return false
	default:
		return false
	}
}

func main() {
	var animals []Animal
	animals = append(animals, Rabbit{})
	animals = append(animals, Dog{})
	for _, animal := range animals {
		fmt.Println(animal.Eat(Grass{}))
	}
}

而在js里我们可以这样写

const Grass = {
    kind: "Grass"
}
const Beef = {
    kind: "Beef"
}
// inteface like
class Animal {
    eat(food) {
        return false
    }
}
class Dog extends Animal {
    eat(food) {
        switch (food.kind) {
            case "Grass":
                return false
            case "Beef":
                return true
            default:
                return false
        }
    }
}
class Rabbit extends Animal {
    eat(food) {
        switch (food.kind) {
            case "Grass":
                return true
            case "Beef":
                return false
            default:
                return false
        }

    }
}

const animals = [new Rabbit(), new Dog()]
animals.forEach(animal => {
    console.log(animal.eat(Grass))
})

从这个代码来看go 和js 各有冗余,js虽然没有了类型,但是因此得通过对象属性声明类型,go有了类型,但是需要冗余的实现duck type :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions