多语言中的对象声明:同一个数据模型在 6 种语言里怎么写

Table of Contents

多语言中的对象声明:同一个数据模型在 6 种语言里怎么写

当我们从一门语言切换到另一门语言时,最先遇到的问题通常不是算法,而是“这个对象到底应该怎么定义”。

表面上看,各种语言都能定义一个“商品”对象;但真到代码层面,字段命名、构造方式、可见性、默认值、实例化风格都不太一样。

这篇文章用同一个数据模型 Prod 做对照,字段统一为 NamePriceIsActive,看看 C#、C++、Python、Go、JavaScript、Rust 里分别怎么写。

在线执行环境 https://rextester.com

为什么值得专门对比

对象声明不是单纯的语法问题,它往往反映了一门语言默认鼓励的建模方式。

  • Go 偏向简单直接的数据结构。
  • C# 习惯用属性表达业务对象。
  • Python 往往借助类或数据模型库补充约束。
  • Rust 更强调结构体和显式构造。
  • C++ 需要同时考虑封装、性能和接口设计。
  • JavaScript 则更灵活,但也更依赖团队约定。

统一数据模型

假设有数据模型 Prod,字段有 NamePriceIsActive

Go

Go 类型的声明和使用

type Prod struct {
	Name string
	Price int
	IsActive bool
}

lst := []Prod{
    {"iphone", 1000, true},
    {"ipid", 2000, false},
    {"macbook", 3000, true},
}
fmt.Println(lst)

JavaScript

Js 类型/函数的声明和使用

class Prod {
    constructor(name, price, isActive) {
        this.name = name;
        this.price = price;
        this.isActive = isActive;
    }
}

function printProd(item) {
    console.log("name:", item.name, " price:",item.price, " isActive:", item.isActive)
}

let lst = [
    new Prod("iphone", 1000, true),
    new Prod("ipad", 2000, true),
    new Prod("macbook", 3000, true)
]
lst.forEach(printProd)

Rust

Rust 类型/函数的声明和使用

#[derive(Clone, Debug)]
pub struct Prod {
    name: String,
    price: i32,
    is_active: bool,
}
impl Prod {
    fn new(name: String, price: i32, is_active: bool) -> Prod {
        Prod {
            name,
            price,
            is_active,
        }
    }
}

Python

python 类型/函数的声明和使用

class Prod:
    def __init__(self, name: str, price: int, isActive: bool):
        self.Name = name
        self.Price = price
        self.isActive = isActive

如果安装了 pydantic,可以指定字段的类型。还是很推荐的

from pydantic import BaseModel

class Prod(BaseModel):
    Name: str
    Price: int  = 0 # 默认值设置的示例
    isActive: bool

# 没有 __init__ 函数,但是可以从字典中构造实例
lst = [
        Prod(Name="iphone", Price=1000, isActive=True),
        Prod(Name="iphone", isActive=True),
        Prod(**{"Name": "macbook", "Price": 3000, "isActive": True}),
        ]

C++

类型/函数的声明和使用

class Prod {
public:
    // 构造函数:对于基本类型 (int, bool) 使用值传递更高效
    Prod(const std::string& name, int price, bool isActive)
        : m_name(name), m_price(price), m_isActive(isActive) {}
    
    // 编译器会生成默认析构函数
    
    std::string GetName() const {
        return m_name;
    }
    
    void SetName(const std::string& name) {
        m_name = name;
    }
    
    // getter 返回值传递,setter 对于基本类型使用值传递
    int GetPrice() const {
        return m_price;
    }
    
    void SetPrice(int price) {
        m_price = price;
    }
    
    bool GetIsActive() const {
        return m_isActive;
    }
    
    void SetIsActive(bool isActive) {
        m_isActive = isActive;
    }

private:
    std::string m_name;   // 使用 m_ 前缀命名成员变量
    int m_price;
    bool m_isActive;
};

C#

C# 类型/函数的声明和使用

public class Prod
{
    public string Name { get; set; }
    public int Price { get; set; }
    public bool IsActive { get; set; }
}

怎么理解这些差异

如果只是为了把数据先装起来,Go 和 JavaScript 往往最直接;如果更关心业务建模和约束,C#、Python 配合框架、Rust 会更有结构;如果既要控制封装又要兼顾底层细节,C++ 的写法通常会更重一些。

这也是为什么很多人刚跨语言时会不适应:你以为自己在学“新语法”,实际上常常是在适应一种新的建模习惯。

总结

把同一个对象用多种语言各写一遍,比单独背语法更容易形成直觉。

当你下次面对一个陌生技术栈时,可以先问自己三个问题:字段怎么组织、实例怎么构造、约束放在哪里。只要这三个问题想清楚,大部分对象声明代码都不会太难读。

Related Posts

多语言中的变量与函数定义:从语法差异到理解方式

多语言中的变量与函数定义:从语法差异到理解方式 接触的编程语言越多,越会发现一个很现实的问题:概念看起来差不多,但落到具体语法时,每门语言都有自己的表达习惯。

Read More

C++ 面向对象程序设计:继承、虚函数和动态绑定到底在解决什么问题

C++ 面向对象程序设计:继承、虚函数和动态绑定到底在解决什么问题 很多人学 C++ 面向对象时,会背下数据抽象、继承、动态绑定这些术语,但一旦落到代码里,还是容易停留在“语法知道,场景不清楚”的阶段。

Read More

C# lambda 表达式是怎么实现的:为什么捕获变量会这样工作

C# lambda 表达式是怎么实现的:为什么捕获变量会这样工作 很多人第一次深入理解 C# lambda,不是因为它的语法,而是因为它的“行为”看起来有点反直觉。为什么一个局部变量在方法返回之后还能被委托访问?为什么循环里的 lambda 有时会捕获到不同结果?为什么看起来只是一个匿名函数,背后却会影响对象分配和执行结果?

Read More