ข้ามไปยังเนื้อหา

Traits

ใน TypeScript interface ใช้ structural typing: ถ้า object มี shape ตรงตามที่กำหนด (property และ method ครบ) ก็ถือว่า satisfy interface ทันที — ไม่ต้องประกาศอะไรเพิ่ม

Rust trait ใช้ nominal typing: type จะ implement trait ก็ต่อเมื่อคุณเขียน impl Trait for Type ชัดๆ การ match shape ไม่เพียงพอ ความแตกต่างนี้มีผลสำคัญต่อการออกแบบ library และความถูกต้องของโค้ด

TypeScript
// TypeScript — structural typing
interface Greet {
name(): string;
hello(): string;
}
// ไม่ต้องประกาศ explicit — แค่ match shape
const english = {
name: () => "world",
hello() { return `Hello, ${this.name()}!`; }
};
function greetSomething(g: Greet) {
console.log(g.hello());
}
greetSomething(english); // ทำงานได้ — english มี shape ที่ถูกต้อง
Rust
trait Greet {
fn name(&self) -> &str;
// Default method — implementation ฟรี สามารถ override ได้
fn hello(&self) -> String {
format!("Hello, {}!", self.name())
}
}
struct English;
struct Thai;
impl Greet for English {
fn name(&self) -> &str { "world" }
// ใช้ default hello()
}
impl Greet for Thai {
fn name(&self) -> &str { "โลก" }
// Override default
fn hello(&self) -> String {
format!("สวัสดี {}!", self.name())
}
}
fn greet_something(g: &dyn Greet) {
println!("{}", g.hello());
}
fn main() {
greet_something(&English);
greet_something(&Thai);
}

Rust สามารถ auto-generate implementation สำหรับ trait ทั่วไปหลายตัวด้วย #[derive(...)] TypeScript ไม่มีเทียบเท่า — คุณ implement interface ด้วยตนเองหรือใช้ class inheritance

TypeScript
// TypeScript — implement interface ด้วยตนเองหรือใช้ class
interface Printable {
toString(): string;
}
class Point implements Printable {
constructor(public x: number, public y: number) {}
toString(): string {
return `Point { x: ${this.x}, y: ${this.y} }`;
}
clone(): Point {
return new Point(this.x, this.y);
}
}
const p = new Point(1, 2);
console.log(p.toString());
Rust
// Rust — derive trait ทั่วไปอัตโนมัติ
#[derive(Debug, Clone, PartialEq)]
struct Point {
x: f64,
y: f64,
}
fn main() {
let p1 = Point { x: 1.0, y: 2.0 };
let p2 = p1.clone(); // Clone derived
println!("{:?}", p1); // Debug derived — แสดง: Point { x: 1.0, y: 2.0 }
println!("equal: {}", p1 == p2); // PartialEq derived
}
trait Greet {
fn name(&self) -> &str;
fn hello(&self) -> String {
format!("Hello, {}!", self.name())
}
}
struct English;
struct Thai;
impl Greet for English {
fn name(&self) -> &str { "world" }
}
impl Greet for Thai {
fn name(&self) -> &str { "โลก" }
fn hello(&self) -> String {
format!("สวัสดี {}!", self.name())
}
}
fn main() {
let e = English;
let t = Thai;
println!("{}", e.hello());
println!("{}", t.hello());
}
Type system ของ Rust แตกต่างจาก TypeScript ในเรื่อง trait/interface satisfaction อย่างไร?
Coherence (orphan) rule ของ Rust ป้องกันอะไร?
`#[derive(Debug)]` ทำอะไร?