Replies: 7 comments 2 replies
-
|
面向对象是毒药,不知道谁在学校散布了“面向对象是更高级的思想”,在我看来面向对象纯粹是工程性臃肿的代名词,和数学的简洁性是对立面。我超级讨厌面向对象,我正在观望zig语言,如果zig语言支持面向对象,那我会放弃,我赞成基于算子的思想,就像haskell |
Beta Was this translation helpful? Give feedback.
-
|
zoop升级到0.2.x了,这个版本主要是为了去除对 |
Beta Was this translation helpful? Give feedback.
-
|
rust 的 trait 还是挺好的 |
Beta Was this translation helpful? Give feedback.
-
|
Java八股背的 |
Beta Was this translation helpful? Give feedback.
-
|
其实zig的面向对象可以直接采纳C语言对面向对象的实现方式,不是一定要做成java那套 |
Beta Was this translation helpful? Give feedback.
-
|
现在比较新的语言都没有继承了,不要再开倒车了吧? |
Beta Was this translation helpful? Give feedback.
-
|
Zig的OOP应该没有必要搞这么复杂吧,把继承改写为组合就是一种良好的方式,比如下面这种通过组合的单继承实现: pub const A = struct {
a: i32,
pub fn init(a: i32) A {
return .{ .a = a };
}
pub fn deinit(self: *A) void {
self.a = undefined;
}
};
pub const B = struct {
a: A, // 继承自 A
b: i32,
pub fn init(a: i32, b: i32) B {
return .{
.a = .init(a),
.b = b,
};
}
pub fn deinit(self: *B) void {
defer self.a.deinit();
defer self.b = undefined;
}
};
test "single-inherit" {
const std = @import("std");
var b: B = .init(10, 20);
defer b.deinit();
try std.testing.expectEqual(b.a.a, 10);
try std.testing.expectEqual(b.b, 20);
}继承作为一种语义要求比语言层面的强制要求要更好一些。像Rust可以的通过宏和Ref和Deref的重载实现真正单继承的感觉,但这并不是一个适用于所有场景的方案。使用组合来实现继承可以做到对继承树更加细致的控制,继承这一特性本身除了GUI之外基本没有其它特别契合的用途了。 包括用组合实现多继承: pub const A = struct {
a: i32,
pub fn init(a: i32) A {
return .{ .a = a };
}
pub fn deinit(self: *A) void {
self.a = undefined;
}
};
pub const B = struct {
b: i32,
pub fn init(b: i32) B {
return .{ .b = b };
}
pub fn deinit(self: *B) void {
self.b = undefined;
}
};
pub const C = struct {
a: A, // 继承自A
b: B, // 继承自B
c: i32,
pub fn init(a: i32, b: i32, c: i32) C {
return .{
.a = .init(a),
.b = .init(b),
.c = c,
};
}
pub fn deinit(self: *C) void {
// 可用 defer 在语义上明确为 init 的逆序
defer self.a.deinit();
defer self.b.deinit();
defer self.c = undefined;
}
};
test "mult-inherit" {
const std = @import("std");
var c: C = .init(10, 20, 30);
defer c.deinit();
try std.testing.expectEqual(c.a.a, 10);
try std.testing.expectEqual(c.b.b, 20);
try std.testing.expectEqual(c.c, 30);
}以及用组合实现虚继承: const std = @import("std");
const Allocator = std.mem.Allocator;
pub const A = struct {
a: i32,
pub fn init(a: i32) A {
return .{ .a = a };
}
pub fn deinit(self: *A) void {
self.a = undefined;
}
};
pub const B = struct {
a: *A, // 继承自 A
b: i32,
pub fn init(a: *A, b: i32) B {
return .{
.a = a,
.b = b,
};
}
pub fn deinit(self: *B) void {
defer self.a.deinit();
defer self.b = undefined;
}
};
pub const C = struct {
a: *A, // 继承自 A
c: i32,
pub fn init(a: *A, c: i32) C {
return .{
.a = a,
.c = c,
};
}
pub fn deinit(self: *C) void {
defer self.a.deinit();
defer self.c = undefined;
}
};
pub const D = struct {
a: *A, // A 的唯一实例
b: B, // 继承自B
c: C, // 继承自C
d: i32,
pub fn init(allocator: Allocator, a: i32, b: i32, c: i32, d: i32) Allocator.Error!D {
const pa = try allocator.create(A);
pa.* = .init(a);
return .{
.a = pa,
.b = .init(pa, b),
.c = .init(pa, c),
.d = d,
};
}
pub fn deinit(self: *D, allocator: Allocator) void {
self.d = undefined;
self.c.deinit();
self.b.deinit();
self.a.deinit();
allocator.destroy(self.a);
}
};
test "virtual-inherit" {
const allocator = std.testing.allocator;
var d: D = try .init(allocator, 10, 20, 30, 40);
defer d.deinit(allocator);
try std.testing.expectEqual(d.b.a.a, 10);
try std.testing.expectEqual(d.c.a.a, 10);
try std.testing.expectEqual(d.d, 40);
try std.testing.expectEqual(d.b.b, 20);
try std.testing.expectEqual(d.c.c, 30);
d.b.a.a = 15;
try std.testing.expectEqual(d.c.a.a, 15);
}当然,对于多继承和单继承也可以持有父类指针而非实例,不过就多了需要在堆上分配的内存,但对父类很大的情况,这可以提升值的复制/移动效率;字段的访问也可以像其它支持class的语言一样包装成getter/setter函数,对外提供一个简易的接口,外部调用者不需要关心内部是如何组织的。别的支持class的语言的继承机制本质上也都大差不差也都是这么搞的。 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
github: https://github.com/zhuyadong/zoop
Beta Was this translation helpful? Give feedback.
All reactions