A better C:from C++, Go,Rust to Zig

发布于 2024-06-23  112 次阅读



从C语言诞生已经五十多年了,现在已经有了许多高级语言,其中很多背靠大厂,比如Java,Go,C#,Dart,Swift等等(甲骨文,谷歌微软和苹果,这类语言通过公司更新).也有很多社区的语言,比如Python,Rust,PHP,Ruby等(这类语言往往通过早期创建者和一些核心成员更新和维护,这里面也有很多开源的语言,允许其他人修改).
相较于公司旗下的语言,社区类型的语言往往更加简洁,在使用或者生产下效率高,但也存在生态相对较差、工具链不够、更新发力不够持久、文档不够丰富的问题.

而 A better C的意思就是在后面的语言中找到性能较强,使用友好并且生态持续发展的语言.TLDR:在大型项目上还是使用C++,在一些工具链或者代码重构上可以考虑Rust.

“世上其实只有两种编程语言,一种是大家一直喷它难用的,一种是根本没人用的。” —— C++ 的作者 Bjarne Stroustrup

相对于Java,C#这种语言,我们尝试找到使用上更加轻型(指的是不依赖某种领域),性能更强占用更小的语言.

Better C

C++

C++20目前已经有了很多Modern的特性,但是目前仍然缺乏的依然还是build system,test harness, linter,C++社区整体比较离散,也没有大公司拿出类似js的all in one的工具链,目前用得多的是vcpkg+cmake. 也有conan和xmake等等,但相对来说还是有欠缺,主要原因是C++没有所谓的官方,只有c++标准委员会,也不像其他公司常用的编程语言会有公司推出工具链.

但C++语言本身还是不错的,足够底层,足够值得学习.

Go

Go背靠谷歌,生态目前感觉还是不够明朗,个人感觉可能是云原生基础设施上,如果你写过Go,就知道大型Web项目写Go还是有所欠缺,拿来写事务还是麻烦.

并且go的nil错误处理,module等依然遭受诟病.但是Go本身代码还是很容易读的,而且工具链也相对完善,有包管理工具,项目构建也可以使用cmake.

Rust

Rust,最近几年热度很高,但是也存在不少问题,上手门槛高,需要额外理解的概念不少.

Rust的一些优势包括以下几点:

  • 并发和并行:Rust内置对并行编程的支持,以及安全高效的多线程特性
  • 性能:由于Rust代码不需要运行时,同时它不需要额外的垃圾回收器功耗,从而可以使用更少的资源并提高性能,
  • 内存安全且无垃圾回收:由于所有权和借用等规则,Rust在没有垃圾回收器的情况下管理内存,从而实现更高效和可预测的性能
  • 跨平台兼容性:Rust支持跨平台开发,意味着可以在多个系统上编译代码而不需要太多的修改代码
  • 强大的生态系统:Rust拥有强大的工具和库生态系统。它的包管理器Cargo显著简化了依赖管理和与外部库集成的难度
struct Person {
    name: String,
    age: u32,
}

impl Person {
    fn new(name: &str, age: u32) -> Person {
        Person {
            name: String::from(name),
            age,
        }
    }

    fn greet(&self) {
        println!("Hello, my name is {} and I'm {} years old.", self.name, self.name);
    }
}

fn main() {
    let alice = Person::new("Alice", 30);
    alice.greet();
}
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

fn move_player(direction: Direction) {
    match direction {
        Direction::Up => println!("Moving up"),
        Direction::Down => println!("Moving down"),
        Direction::Left => println!("Moving left"),
        Direction::Right => println!("Moving right"),
    }
}

fn main() {
    move_player(Direction::Up);
    move_player(Direction::Left);

Zig

Zig官方是这么说的:Zig 是一种通用的编程语言和工具链,用于维护健壮最优可重用的软件.

既然有了C++和Rust,为什么又要搞这么多东西?有了 C++、D 和 Rust,为什么还需要 Zig? ⚡ Zig Programming Language (ziglang.org)

const std = @import("std");
const parseInt = std.fmt.parseInt;

test "parse integers" {
    const input = "123 67 89,99";
    const ally = std.testing.allocator;

    var list = std.ArrayList(u32).init(ally);
    // Ensure the list is freed at scope exit.
    // Try commenting out this line!
    defer list.deinit();

    var it = std.mem.tokenizeAny(u8, input, " ,");
    while (it.next()) |num| {
        const n = try parseInt(u32, num, 10);
        try list.append(n);
    }

    const expected = [_]u32{ 123, 67, 89, 99 };

    for (expected, list.items) |exp, actual| {
        try std.testing.expectEqual(exp, actual);
    }
}
const std = @import("std");

pub fn main() !void {
    const x: i32 = 5;
    const y: i32 = 10;
    const sum = x + y;
    std.log.info("The sum of {} and {} is {}", .{ x, y, sum });
}
const std = @import("std");

fn greet(name: []const u8) void {
    std.log.info("Hello, {}!", .{name});
}

pub fn main() !void {
    greet("Alice");
    greet("Bob");
}

官方文档阐述了非常多Zig的优势,看起来特别吸引人,但是目前使用的人还是不多.

Zig的一些劣势包括:

  • 有限的生态系统:因为它仍处于早期阶段,Zig语言的生态系统比成熟语言更小
  • 成熟度和工具:Zig是一种新语言,还有改进的空间。但请注意,仍然有一个强大而活跃的社区支持它
  • 互操作性挑战:Zig提供了用于兼容性的C接口,但与其他语言集成可能需要额外的工作,比如管理数据转换和语言之间的通信
  • 文档可用性:Zig是一种相对较新的语言,因此文档有限,社区正在努力提高文档的可用性

开发者可以在系统编程中使用Zig来构建操作系统、设备驱动程序和嵌入式系统。其还在命令行工具中也有很多应用场景,可用于创建高效和快速的命令行界面,构建系统脚本,或优化现有工具的性能。

在编译器和语言开发中,Zig以其元编程能力和对简易性的追求而闻名。比较著名的开源项目是Bun,其是一个使用Zig开发的JavaScript运行时。

与Rust一样,Zig也有一些更为专业的使用场景:

  • 游戏开发,因支持高性能游戏引擎、能够实时模拟
  • 在嵌入式系统和物联网中,用于编程微控制器、传感器和其他资源受限设备
  • 在密码应用中,用于实现加密算法、数字签名、安全通信协议和其他安全敏感组

小小的BenchmarkA "Better C" Benchmark (zserge.com)

我为什么会看上面这些语言的比较,主要原因还是:C++很好,但没有完善的工具链,它的标准委员会也不会管这些,而一些大厂也没有开源一些工具使用;

Go的生态位跟C/C++和Rust这类语言还不一样;Rust的上手门槛高,但目前看来是最可行的C/C++在系统编程、工具链重构甚至于一些业务处理上的可行工具.

而Zig还远远没有完善,但上手门槛相对更低.更何况c语言即使到今天也在更新,生态还是在的.

题外话

之前一段时间有个叫Mojo的编程语言不断在宣传自己的在AI领域编程的地位:比C和Python性能更好.Mojo 🔥: Programming language for all of AI (modular.com)

目前还在吹水建设阶段,看后续表现(其实大众看的是有没有相关大厂进局).

我常常会关注一些本身比较老但使用并不少的编程语言,因为这类编程语言有自己的生态位,文档可能不算新,官方网站也往往看起来很老,生态上也没有很大的持续发力点,但是我还是会时不时看看,毕竟其中很多可能也会用上.

PHP

之前的文章我也提到过,php生态位就是web,也是为web而生.你甚至不需要特意使用某些web框架来创建应用,它本身就支持很多操作.但是php本身有些语法还需要适应(很多人说语法丑陋).而它的web框架也特别多,从相对轻量ThinkPHP、Symfony到重型的Laravel,都可以试试.Swoole框架也使得从Web到 TCP、UDP、Socket上

还有相比swoole更易学习的workerman,workerman 是纯php写的网络框架.支持TCP长连接,支持Websocket、HTTP等协议.以及基于workerman的webman,webman用于替代传统的php-fpm架构,提供超高性能可扩展的HTTP服务。你可以用webman开发网站,也可以开发HTTP接口或者微服务

<?php
$numbers = array(1, 2, 3, 4, 5);
echo "The first number is: " . $numbers[0];
echo "The length of the array is: " . count($numbers);

$person = array(
    "name" => "Alice",
    "age" => 30
);
echo "Name: " . $person["name"] . ", Age: " . $person["age"];
?>
class Person {
    private $name;
    private $age;

    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }

    public function greet() {
        echo "Hello, my name is " . $this->name . " and I'm " . $this->age . " years old.";
    }
}

$alice = new Person("Alice", 30);
$alice->greet(); // 输出 "Hello, my name is Alice and I'm 30 years old."
function divide($a, $b) {
    if ($b == 0) {
        throw new \Exception("Division by zero");
    }
    return $a / $b;
}

try {
    $result = divide(10, 0);
} catch (\Exception $e) {
    echo "Error: " . $e->getMessage();
}
$greet = function($name) {
    echo "Hello, $name!";
};

$greet("Alice"); // 输出 "Hello, Alice!"

$numbers = [1, 2, 3, 4, 5];
$doubledNumbers = array_map(function($x) {
    return $x * 2;
}, $numbers);

print_r($doubledNumbers); // 输出 [2, 4, 6, 8, 10]

推荐学习:

Ruby

也是web生态,或者说应为rails而知名.国内相对来说没那么多使用ruby的.

numbers = [1, 2, 3, 4, 5]
puts "The first number is: #{numbers[0]}"
puts "The length of the array is: #{numbers.length}"

person = {
  "name" => "Alice",
  "age" => 30
}
puts "Name: #{person["name"]}, Age: #{person["age"]}"
class Person
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def greet
    puts "Hello, my name is #{@name} and I'm #{@age} years old."
  end
end

# 创建 Person 对象并调用方法
alice = Person.new("Alice", 30)
alice.greet # 输出 "Hello, my name is Alice and I'm 30 years old."

推荐学习:

Lua

lua生态位是写一些游戏脚本或者一些工具的功能,比如neovim中的一些插件就会使用lua.另外一些嵌入式设备也会使用,主要是与其他语言搭配.这门语言本身非常小,

local x = 5
local y = 10
local sum = x + y
print("The sum of " .. x .. " and " .. y .. " is " .. sum)
local fruits = {"apple", "banana", "orange"}

-- 使用for循环遍历
for i=1, #fruits do
    print(fruits[i])
end

-- 使用for-in循环遍历
for _, fruit in ipairs(fruits) do
    print(fruit)
end
-- 定义一个Person类
local Person = {}
function Person:new(name, age)
    local obj = {
        name = name,
        age = age
    }
    setmetatable(obj, self)
    self.__index = self
    return obj
end

function Person:greet()
    print("Hello, my name is " .. self.name .. " and I'm " .. self.age .. " years old.")
end

-- 创建Person对象并调用方法
local alice = Person:new("Alice", 30)
alice:greet()
-- 定义一个协程函数
local function count(n)
    for i=1,n do
        coroutine.yield(i)
    end
end

-- 创建并控制协程
local co = coroutine.create(count)
print(coroutine.resume(co, 5)) -- 输出 1
print(coroutine.resume(co)) -- 输出 2
print(coroutine.resume(co)) -- 输出 3
print(coroutine.resume(co)) -- 输出 4
print(coroutine.resume(co)) -- 输出 5
print(coroutine.resume(co)) -- 输出 nil
-- 定义一个Vector2D类
local Vector2D = {}
Vector2D.__index = Vector2D

function Vector2D:new(x, y)
    local obj = setmetatable({x=x, y=y}, Vector2D)
    return obj
end

function Vector2D:add(other)
    return Vector2D:new(self.x + other.x, self.y + other.y)
end

function Vector2D:__tostring()
    return "(" .. self.x .. ", " .. self.y .. ")"
end

-- 创建和操作Vector2D对象
local v1 = Vector2D:new(1, 2)
local v2 = Vector2D:new(3, 4)
local v3 = v1:add(v2)
print(v3) -- 输出 (4, 6)

一些有趣的东西

[Worst Programming Languages to Learn in 2018 (codementor.io)这篇文章在2018年给出了在工作上不推荐碰的语言,其中包括Dart,Rust,Ruby,Go等,事实上从工作的角度来看,一些函数式编程语言和门槛较高的语言上榜很正常,但是另外有些更可能是因为生态还不够大,但本身是做应用的,比如Dart和Go,所以还需要官网.

这份榜单比较激进,但总体还是很有趣的.像函数时语言Clojure和Elixir就相比更老的Haskell和Erlang就更好.

在2019年Study of Programming Languages Not to Learn in 2019 (codementor.io)

这份榜单变得更符合我的知觉了,当然这些东西只是看看而已,比如下面的人就说自己拿CoffeeScript写应用到AppStore上赚了很多钱,所以,还是要看生态位.

image-20240623122150477
届ける言葉を今は育ててる
最后更新于 2024-06-30