文/一个用二十多种语言写过Hello World的收集癖
我的GitHub上有个叫”hello-world-collection”的仓库,里面放了用各种编程语言写的Hello World。不是那种只在终端里打印一句话的,而是每一种都尽可能按照这门语言的惯用风格来写——该建类的建类,该用包的用包,该遵循的命名规范一条不落。
现在这个仓库有二十八种语言了。每次学一门新语言,我做的第一件事就是给它建个文件夹,然后把Hello World按照那门语言的”行规”认认真真写一遍。
写得多了,我慢慢发现一件事:每种语言的Hello World,其实都在无声地告诉你这门语言的设计哲学。它怎么写、要写多少行、上下文长什么样,背后全是讲究。
C语言的Hello World:你离硬件有多近
c
include
int main() {
printf(“Hello, World!\n”);
return 0;
}
六行代码。你包含了头文件,你声明了主函数,你调用了标准库的输出函数,你显式地返回了一个整数。
C语言的Hello World在告诉你:你得知道自己要什么。包含什么库、函数怎么调用、返回什么值,全部要写清楚。这门语言不替你做任何”隐式”的决定。所有的依赖、所有的入口、所有的返回值,都明明白白摆在那里。
这种透明是有代价的——你得写更多行。但它也有好处:你永远知道每一行在干什么,没有任何魔法。
我的仓库里C语言的Hello World旁边写着一段注释:”这是所有现代语言的爷爷。它不惯着你,但它让你知道自己在干什么。”
Python的Hello World:信达雅,越短越好
python
print(“Hello, World!”)
就一行。没有头文件,没有主函数,没有返回值,没有任何多余的东西。
Python的Hello World在告诉你:把精力花在解决问题上,别花在伺候语法上。既然你只是想打印一句话,那就只写打印这一件事。多余的,全是噪声。
这种极简是Python安身立命的根本。它有强大的标准库、海量的第三方包,你永远可以用最少的代码做最多的事。但代价是有些事情你没法精准控制——内存管理、线程调度、底层优化,这些细节被封装在了”魔法”背后。
新手喜欢Python,因为上手快。老手也喜欢Python,因为写起来快。就是快。
Java的Hello World:你得按规矩来
java
public class HelloWorld {
public static void main(String[] args) {
System.out.println(“Hello, World!”);
}
}
七行。类名必须大写开头、文件必须和类同名、main方法必须是public static void、参数必须是String数组。一样不能少,一样不能错。
Java的Hello World在告诉你:这个世界是有规矩的。按规矩来,你就能活得好。不按规矩,编译器连门都不让你进。
Java的设计哲学是”写一次,跑到处”。为了实现这个目标,它建立了严密的规则体系:强类型、严格的面向对象、严谨的命名规范。每个Java程序员写的代码放在一起,风格不会差太远。这种一致性让大型团队协作变得可能——你接手别人的代码,不会感觉像进了别人的家。
但代价是仪式感太重了。你就想打个招呼,结果得先穿西装打领带。
Go语言的Hello World:务实,不废话
go
package main
import “fmt”
func main() {
fmt.Println(“Hello, World!”)
}
五行的同时,你能感觉到一种”恰到好处”的分寸感。有包声明,有导入,有函数,但省掉了类、省掉了分号、省掉了复杂的继承结构。
Go的Hello World在告诉你:我要解决问题,但我不搞形式主义。该有的结构要有,不该有的修饰一概不要。
Go是Google为了解决大规模服务端开发痛点而造的。它不追求极简到Python那种程度,也不追求严谨到Java那种程度。它要的是”写着顺手,看着顺眼,跑着顺溜”。它的Hello World就像它的设计者——务实的中年人,不追求花活,但什么事都能办好。
Rust的Hello World:安全的执念
rust
fn main() {
println!(“Hello, World!”);
}
看起来跟Go差不多。但就这四行代码,Rust编译器在后面做了巨量的事情:检查所有权、检查生命周期、检查变量是否被正确初始化。你在写的时候感受不到,但它一直在盯着。
Rust的Hello World在告诉你:每一行代码的安全,都由我来守护。你可以放心大胆地写,出了任何内存问题,那一定是我搞错了,你只管说你想要什么。
Rust是目前唯一一门能让系统级编程变得安全又现代的语言。但代价是你必须遵循它的规则——那些关于借用、所有权、生命周期的规则,刚开始会让你头大如斗。可一旦你适应了,你会发现它替你拦下了太多C语言里会踩的坑。
JavaScript的Hello World:灵活到没有标准答案
javascript
console.log(“Hello, World!”);
或者
javascript
alert(“Hello, World!”);
或者写在HTML里:
html
JavaScript的Hello World有至少十种写法。在浏览器里是一种,在Node.js里是一种,在Deno里又是另一种。甚至在不同的框架里,写法也千差万别。
JS的Hello World在告诉你:我不管你怎么写,能跑就行。我是最宽容的语言,你可以用任何方式、在任何一个环境里让我输出那句话。你灵活,我比你更灵活。
这种灵活性成就了JavaScript今天的统治地位——它几乎无处不在。但也让这门语言背负了很多骂名:隐式类型转换、this指向诡异、回调地狱。它的Hello World越多变,就越折射出这门语言的多元宇宙性格。
Haskell的Hello World:纯到不能再纯
haskell
main = putStrLn “Hello, World!”
看起来简单,但它背后是纯函数式编程的整套哲学。一个”副作用”——让屏幕显示字符——在Haskell里是被严格管控的。你不能随随便便就输出,你得通过putStrLn这个IO操作,把它放到一个叫”IO Monad”的容器里,然后由运行时去执行。
Haskell的Hello World在告诉你:在纯数学的世界里,没有副作用。一切变化都是状态,一切状态都要被显式管理。你不懂数学,就别想懂我。
这可能是所有语言里门槛最高的一门。但它在学术界的地位无可撼动,因为它把”函数式编程”推到了极致。
写在最后:从一个Hello World看透一门语言的魂
每一次我对着一个新语言的Hello World发呆的时候,我都在做一件事:试图理解这门语言想告诉我什么。
C说:你要坦荡,每一行都是你的责任。
Python说:你要简单,一件一件事情做好。
Java说:你要规矩,守规矩才能成方圆。
Go说:你要务实,解决问题的才是好代码。
Rust说:你要安全,任何时候都不能崩溃。
JavaScript说:你要灵活,适应万物才是生存之道。
Haskell说:你要纯粹,回到数学的原点。
没有哪一种是错的。它们只是写给不同的人、解决不同的问题、在不同的时代背景下诞生的产物。
但有趣的是,无论它们用什么姿势、写多少行、加多少修饰——它们输出的结果,永远是那同样的十三个字符。
Hello, World!
这大概是编程世界里最奇妙的一件事:道不同,但问候相同。每一种语言都用自己最舒服的方式,向这个世界打了同样的招呼。然后,各自去往各自该去的战场。
所以如果你问我要学哪门语言,我的回答是:先去看看它们的Hello World怎么写。你看完那几行代码,心里对那门语言的第一感觉,通常就是它最适合你的地方。
那种感觉,骗不了人。