TS and Go 之 class

Go 中的类似 class 实现

我们知道,Go 中没有 class 关键字,类似 "class" 的定义是通过 struct 来实现的。

go 复制代码
type Student struct {
	Name string
	Sex  string
	Age  int
}

func (s Student) Greet() {
	fmt.Println("Hello, my name is ", s.Name, " my age is ", s.Age)
}

Go 中的写法与传统的面向对象不同:

  • method 通过在方法名前面制定 struct 来实现,而不是将方法写进 stuct 中。
  • method 可以有效的跟 struct 分离,甚至可以写在不同的文件中。

实现类似继承的方式也很简单:

go 复制代码
type CollegeStudent struct {
	Student
	Major string
}

TS 中的类似 class 的另一种实现方式

我们知道,TS 中有 class 关键字,用来实现类。上述功能的实现:

ts 复制代码
class Student {
    name: string;
    age: number;
    sex: string

    greet() {
        console.log("Hello, my name is ", this.name, " my age is ", this.age);
    }
}

有时候当一个 class 会非常大。比如我们有个斜杠少年,他同时是外卖员,滴滴司机和程序员。他需要同时具备外卖员滴滴司机程序员几种不同的 method。那通过 class 来实现的话,我们很容易想到,我们可以分别定义三个不同的 interface, 然后 实现它。比如:

ts 复制代码
interface DidiDriver {
    drive: () => void;
}

interface MeituanWaiMai {
    deleveFood: () => void;
}

interface Coder {
    code: () => void;
}

class XieGang implements DidiDriver, MeituanWaiMai, Coder {
    name: string;
    code: () => void;
    deleveFood: () => void;
    drive: () => void;
}

这里依然有一个问题,虽然我们接口可以分开,但是逻辑的实现我们依然要写在 class 中。如果每一个角色都有十几种不同的 method 的话,class 就会变得非常大。当然,我们可以通过定义不同的 class 再组合实现,这样为了代码整洁却增加了 class 的复杂度。

我们可以看一下 go 中,只需要在 method 中申明 (s Xiegang) methodName, 就可以把 method 写进不同的文件中,比如:

scss 复制代码
type XieGang struct {
    Name string
}

// in Didi file
func (x XieGang) drive() {
    fmt.Println(x.Name, " is driving")
}
func (x XieGang) anotherDidiMethod() {}

// in meituan file
func (x XieGang) deleveFood() {}
func (x XieGang) anotherMeituanMethod() {}

那么,TS 中是否有类似的实现呢。我们知道 JS 中的 class 本质上依然是 function,是通过 function 来实现的。function 中的 this 可以指向 function 的调用者,并且,我们可以为 this 制定类型。

typescript 复制代码
// 首先,我们定义 interface XieGang
type XieGang = { name: string };

// in Didi file
function code(this: XieGang) {
    console.log(`${this.name} is coding`);
}

...
// 使用时,需要手动绑定 this
const xieGang: XieGang = {name: "Zhang San"}
code.bind(xieGang)();

如果某一天 JS 中的提案实现的话会方便一些:
xieGang::code();
相关推荐
请你喝可乐1 小时前
AI Agent Skill 高阶使用指南:从入门到精通
后端
用户962377954481 小时前
代码审计 | Struts2 —— S2-016 OGNL 注入原理
后端
9号达人2 小时前
为什么你应该在 MQ 里用多个消费者,而不是一个
java·后端·架构
阿星做前端2 小时前
重度 AI 编程用户的一天:我怎么把 Claude Code / Codex 工作流搬进浏览器工作台
前端·javascript·后端
代码羊羊2 小时前
Rust 类型转换全方位通俗易懂指南(as、TryInto、强制转换、Transmute)
后端·rust
jay神2 小时前
基于SpringBoot的宠物生命周期信息管理系统
java·数据库·spring boot·后端·web开发·宠物·管理系统
星栈2 小时前
Rust 全栈一个 main.rs 搞定启动:migration + CQRS + 投影监听,部署只需一个二进制
后端·架构
Penge6662 小时前
一文理清 Mac/Linux 终端配置文件(.bash_profile, .bashrc, .zshrc)
后端
Rust研习社2 小时前
Rust 性能陷阱:那些看起来很优雅但很慢的写法(上)
后端·rust·编程语言
万亿少女的梦1682 小时前
基于SpringBoot的在线考试管理系统设计与实现
java·spring boot·后端