Rust与Go:现代系统编程语言的深度对比

引言

在现代软件开发领域,Rust和Go都是备受瞩目的系统编程语言。Go由Google于2009年发布,以简洁、高效的并发模型著称;Rust则由Mozilla于2015年正式发布,以内存安全和零成本抽象而闻名。两者都试图解决传统系统编程语言(如C/C++)的痛点,但采用了截然不同的设计哲学。

本文将从内存管理、并发模型、性能表现、生态系统等多个维度,深入对比这两门语言,帮助开发者更好地理解它们各自的优势和适用场景。

一、设计哲学的差异

Go的设计哲学:简单至上

Go的设计遵循"少即是多"的原则,其核心目标是简单性生产力

  • 语法简洁,学习曲线平缓
  • 内置垃圾回收(GC),降低内存管理负担
  • 标准库功能丰富,"batteries included"
  • 编译速度快,适合快速迭代

Rust的设计哲学:安全与性能并重

Rust追求的是零成本抽象内存安全

  • 通过所有权系统在编译期保证内存安全
  • 无需垃圾回收器,性能可预测
  • 提供底层控制能力,同时保证安全性
  • 强大的类型系统和编译时保证

二、内存管理:GC vs 所有权系统

Go:垃圾回收器

Go采用自动垃圾回收来管理内存,开发者无需手动管理内存的分配和释放:

go 复制代码
package main

import "fmt"

type User struct {
    Name  string
    Email string
}

func createUser(name string, email string) *User {
    user := &User{
        Name:  name,
        Email: email,
    }
    // 即使返回局部变量的指针,GC也会自动处理
    return user
}

func main() {
    user := createUser("张三", "zhangsan@example.com")
    fmt.Printf("User: %s, %s\n", user.Name, user.Email)
    // 不需要手动释放内存,GC会自动回收
}

优势

  • 编程简单,降低心智负担
  • 避免悬垂指针、内存泄漏等常见错误

劣势

  • GC引入运行时开销和停顿(STW - Stop The World)
  • 内存使用效率相对较低
  • 性能不可预测,对延迟敏感的应用不友好

Rust:所有权系统

Rust通过独特的所有权系统在编译期就确保内存安全,无需运行时GC:

rust 复制代码
struct User {
    name: String,
    email: String,
}

fn create_user(name: String, email: String) -> User {
    User {
        name,
        email,
    }
}

fn main() {
    let user = create_user(
        String::from("张三"),
        String::from("zhangsan@example.com")
    );
    
    println!("User: {}, {}", user.name, user.email);
    
    // user在作用域结束时自动释放,无需GC
}

所有权规则

rust 复制代码
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // s1的所有权转移给s2
    
    // println!("{}", s1); // 编译错误!s1已经无效
    println!("{}", s2); // 正确
}

优势

  • 零运行时开销,性能可预测
  • 在编译期就能发现内存错误
  • 内存使用效率高
  • 适合实时系统和嵌入式开发

劣势

  • 学习曲线陡峭,需要理解所有权、借用、生命周期等概念
  • 编译器检查严格,初学者容易"与编译器搏斗"

三、并发模型:Goroutine vs Async/Await

Go:Goroutine与Channel

Go的并发模型基于CSP(Communicating Sequential Processes)理论,通过goroutine和channel实现:

go 复制代码
package main

import (
    "fmt"
    "time"
)

func fetchURL(url string, ch chan<- string) {
    // 模拟网络请求
    time.Sleep(100 * time.Millisecond)
    ch <- fmt.Sprintf("Data from %s", url)
}

func main() {
    urls := []string{
        "https://api1.example.com",
        "https://api2.example.com",
        "https://api3.example.com",
    }
    
    ch := make(chan string)
    
    // 启动多个goroutine
    for _, url := range urls {
        go fetchURL(url, ch)
    }
    
    // 接收结果
    for range urls {
        result := <-ch
        fmt.Println(result)
    }
}

特点

  • Goroutine非常轻量(初始栈只有2KB)
  • 语法简单直观(只需在函数调用前加go
  • Channel提供了优雅的数据同步机制
  • 运行时调度器自动管理

Rust:Async/Await与Tokio

Rust采用零成本的异步模型,配合Tokio等运行时使用:

rust 复制代码
use tokio::time::{sleep, Duration};

async fn fetch_url(url: &str) -> String {
    // 模拟网络请求
    sleep(Duration::from_millis(100)).await;
    format!("Data from {}", url)
}

#[tokio::main]
async fn main() {
    let urls = vec![
        "https://api1.example.com",
        "https://api2.example.com",
        "https://api3.example.com",
    ];
    
    // 并发执行多个异步任务
    let tasks: Vec<_> = urls
        .iter()
        .map(|url| fetch_url(url))
        .collect();
    
    let results = futures::future::join_all(tasks).await;
    
    for result in results {
        println!("{}", result);
    }
}

Rust的线程安全保证

rust 复制代码
use std::sync::Arc;
use tokio::sync::Mutex;

#[derive(Debug)]
struct Counter {
    value: i32,
}

#[tokio::main]
async fn main() {
    let counter = Arc::new(Mutex::new(Counter { value: 0 }));
    let mut handles = vec![];
    
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = tokio::spawn(async move {
            let mut c = counter.lock().await;
            c.value += 1;
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.await.unwrap();
    }
    
    println!("Final value: {}", counter.lock().await.value);
}

对比总结

特性 Go Rust
并发原语 Goroutine + Channel Async/Await + Future
运行时 内置运行时 需要选择运行时(Tokio等)
内存开销 每个goroutine约2KB 每个task约几百字节
编译时检查 弱(数据竞争在运行时检测) 强(编译期防止数据竞争)
学习曲线 平缓 陡峭

四、性能对比:基准测试

1. CPU密集型任务

斐波那契数列计算(Go)

go 复制代码
package main

import (
    "fmt"
    "time"
)

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n-1) + fibonacci(n-2)
}

func main() {
    start := time.Now()
    result := fibonacci(42)
    duration := time.Since(start)
    
    fmt.Printf("Result: %d, Time: %v\n", result, duration)
}

斐波那契数列计算(Rust)

rust 复制代码
use std::time::Instant;

fn fibonacci(n: u32) -> u32 {
    if n <= 1 {
        return n;
    }
    fibonacci(n - 1) + fibonacci(n - 2)
}

fn main() {
    let start = Instant::now();
    let result = fibonacci(42);
    let duration = start.elapsed();
    
    println!("Result: {}, Time: {:?}", result, duration);
}

性能对比(参考值):

  • Rust: ~1.5秒
  • Go: ~2.3秒

Rust在纯计算任务上通常快20-50%。

2. 内存密集型任务

大数组处理(Rust)

rust 复制代码
fn process_array(size: usize) -> Vec<i32> {
    let mut data: Vec<i32> = (0..size as i32).collect();
    
    // 原地修改,无额外分配
    for item in data.iter_mut() {
        *item = *item * 2 + 1;
    }
    
    data
}

fn main() {
    let result = process_array(10_000_000);
    println!("Processed {} items", result.len());
}

大数组处理(Go)

go 复制代码
func processArray(size int) []int {
    data := make([]int, size)
    for i := 0; i < size; i++ {
        data[i] = i
    }
    
    // 原地修改
    for i := range data {
        data[i] = data[i]*2 + 1
    }
    
    return data
}

func main() {
    result := processArray(10_000_000)
    fmt.Printf("Processed %d items\n", len(result))
}

内存使用对比

  • Rust:内存使用精确,无GC开销
  • Go:GC需要额外的内存空间(通常是实际使用的2-3倍)

3. 并发性能

并发HTTP服务器性能对比

在实际测试中(如Techempower Benchmark):

  • Rust(Actix-web):每秒可处理600k+ 请求
  • Go(Gin/Echo):每秒可处理400k+ 请求

Rust的优势在于:

  • 无GC停顿
  • 更低的内存占用
  • 更好的缓存局部性

五、实战案例:构建高性能Web API

Go实现

该代码实现了一个功能完整、设计规范的用户管理 API 服务,适合作为 Go 语言 Web 开发的入门示例或基础原型。其优点在于:

  • 结构清晰,分层明确(数据模型、存储层、接口层);
  • 并发安全,处理多请求场景可靠;
  • 遵循 REST 规范,接口易用且符合行业标准;
  • 轻量化设计,便于测试和扩展。

如需用于生产环境,可扩展存储层(对接数据库)、增加认证授权、添加请求验证等功能。

Rust实现(使用Actix-web)

对比分析

  1. 代码复杂度:Go代码更简洁,Rust需要更多的类型声明和生命周期管理
  2. 安全性:Rust在编译期就能防止数据竞争,Go需要运行时检测
  3. 性能:Rust版本在高并发场景下通常有更好的性能和更低的延迟
  4. 开发效率:Go的开发速度更快,适合快速原型开发

六、错误处理机制

Go:多返回值与panic

go 复制代码
package main

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 0)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("Result: %f\n", result)
}

特点

  • 显式错误检查(if err != nil)
  • 简单直观,但代码冗长
  • panic用于不可恢复的错误

Rust:Result与Option类型

rust 复制代码
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("division by zero"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 0.0) {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
    
    // 或使用更简洁的方式
    let result = divide(10.0, 2.0).unwrap_or(0.0);
    println!("Result: {}", result);
}

链式调用

rust 复制代码
use std::fs::File;
use std::io::Read;

fn read_file_length(path: &str) -> Result<usize, std::io::Error> {
    let mut file = File::open(path)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents.len())
}

特点

  • 类型系统强制错误处理
  • 支持优雅的链式调用(? 操作符)
  • 编译器确保不会忽略错误

七、生态系统对比

Go生态

优势

  • 标准库强大且稳定
  • 官方工具链完善(go fmt, go test, go mod)
  • Web框架成熟(Gin, Echo, Fiber)
  • 云原生生态丰富(Docker、Kubernetes都用Go编写)

热门库

go 复制代码
// Web框架
import "github.com/gin-gonic/gin"

// 数据库
import "gorm.io/gorm"

// Redis客户端
import "github.com/go-redis/redis/v8"

Rust生态

优势

  • Cargo包管理器体验优秀
  • 性能关键库(序列化、加密等)性能出众
  • 跨平台能力强(包括WebAssembly)
  • 系统编程工具丰富

热门库

rust 复制代码
// Web框架
use actix_web;
use axum;

// 异步运行时
use tokio;

// 序列化
use serde;

// 数据库
use sqlx;
use diesel;

Cargo.toml示例

toml 复制代码
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1.35", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
actix-web = "4.4"
sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres"] }

八、开发体验对比

编译速度

  • Go:编译速度非常快,大型项目通常在几秒内完成
  • Rust:编译速度较慢,大型项目可能需要几分钟(首次编译)

IDE支持

  • Go:GoLand、VS Code(Go扩展)支持优秀
  • Rust:Rust-analyzer提供出色的IDE体验,VS Code、IntelliJ IDEA都有良好支持

学习曲线

复制代码
难度评级(1-10):
- Go: 3-4(容易上手)
- Rust: 7-8(需要投入更多时间学习)

调试体验

Go

go 复制代码
// 简单的打印调试
fmt.Printf("Debug: %+v\n", someStruct)

// 使用Delve调试器
// $ dlv debug

Rust

rust 复制代码
// 使用dbg!宏
dbg!(&some_variable);

// 使用LLDB/GDB调试器
// $ rust-gdb target/debug/my_program

九、适用场景分析

选择Go的场景

  1. 微服务和API开发
    • 快速开发和迭代
    • 团队协作项目(学习曲线低)
    • 云原生应用
  2. 网络编程
    • Web服务器
    • RPC服务
    • 代理和网关
  3. DevOps工具
    • CI/CD工具
    • 监控系统
    • 容器编排

案例

  • Docker(容器引擎)
  • Kubernetes(容器编排)
  • Prometheus(监控系统)
  • Etcd(分布式键值存储)

选择Rust的场景

  1. 系统编程
    • 操作系统组件
    • 文件系统
    • 驱动程序
  2. 性能关键应用
    • 游戏引擎
    • 数据库引擎
    • 音视频处理
  3. 嵌入式系统
    • IoT设备
    • 固件开发
    • 实时系统
  4. WebAssembly
    • 浏览器高性能计算
    • 跨平台应用

案例

  • Firefox(浏览器组件用Rust重写)
  • Cloudflare Workers(边缘计算平台)
  • Discord(部分后端服务)
  • Figma(实时协作引擎)

十、实战:命令行工具开发

Go实现:文件搜索工具

searchFiles是一个轻量高效的本地文件搜索工具函数,其设计核心是 "按需过滤、快速终止":

  • 通过多条件过滤精准定位目标文件,满足不同场景需求(如按类型、名称模式搜索);
  • 结合遍历终止机制和提前过滤,优化性能,避免资源浪费;
  • 代码简洁易读,可扩展性强(如后续可添加文件内容匹配、修改时间过滤等功能)。

该函数适合集成到文件管理工具、命令行搜索脚本等场景,帮助用户快速定位本地文件。

searchInFiles文件内容检索的实用工具函数,在文件名搜索的基础上实现了 "内容级匹配",通过行级扫描、匹配次数统计和行号记录,为用户提供精准的文本定位能力。其设计兼顾了灵活性(支持多条件过滤)和实用性(直观展示匹配细节),适合集成到日志分析工具、代码搜索插件等场景,帮助快速从大量文件中定位关键信息。

Rust实现:文件搜索工具

search_file_names是一个类型安全、功能完善的文件名搜索函数,利用 Rust 的迭代器和类型系统优势,实现了简洁且健壮的目录遍历与过滤逻辑。其核心特点包括:

  • 支持文件类型过滤、大小写忽略、结果数量限制等实用功能;
  • 通过迭代器链式调用和Option安全处理,代码简洁且容错性强;
  • 符合 Rust 的内存安全和类型安全原则,避免常见的运行时错误。

该函数可作为命令行工具、文件管理器插件等场景的基础组件,高效实现本地文件的文件名检索需求。

search_file_contents是一个功能完善、鲁棒性强的文件内容搜索函数,借助 Rust 的类型系统和迭代器特性,实现了高效的目录遍历、文件过滤和内容匹配。其核心优势包括:

  • 支持文本内容的行级匹配,记录行号和原始内容,结果精准且易用;
  • 通过错误处理机制跳过不可读文件,确保搜索流程稳定;
  • 兼容大小写忽略、文件类型过滤、结果数量限制等实用功能,适配多种场景。

该函数适合作为命令行搜索工具、IDE 插件或日志分析工具的核心组件,帮助用户快速从大量文件中定位关键内容。

使用Clap改进(Rust)

rust 复制代码
use clap::Parser;
use std::path::PathBuf;

#[derive(Parser)]
#[command(name = "search")]
#[command(about = "A simple file search tool", long_about = None)]
struct Cli {
    /// Directory to search in
    #[arg(short, long)]
    directory: PathBuf,
    
    /// Pattern to search for
    #[arg(short, long)]
    pattern: String,
    
    /// Case insensitive search
    #[arg(short, long)]
    ignore_case: bool,
}

fn main() {
    let cli = Cli::parse();
    
    println!("Searching in: {:?}", cli.directory);
    println!("Pattern: {}", cli.pattern);
    println!("Ignore case: {}", cli.ignore_case);
    
    // 搜索逻辑...
}

十一、跨语言互操作

从Go调用Rust

Rust可以编译为C兼容的库,Go可以通过CGO调用:

Rust库(lib.rs

rust 复制代码
#[no_mangle]
pub extern "C" fn fibonacci(n: u32) -> u32 {
    if n <= 1 {
        return n;
    }
    fibonacci(n - 1) + fibonacci(n - 2)
}

#[no_mangle]
pub extern "C" fn process_data(data: *const u8, len: usize) -> i32 {
    // 处理数据的高性能Rust代码
    if data.is_null() {
        return -1;
    }
    
    let slice = unsafe {
        std::slice::from_raw_parts(data, len)
    };
    
    slice.iter().map(|&x| x as i32).sum()
}

Cargo.toml配置

toml 复制代码
[lib]
crate-type = ["cdylib"]

Go调用

go 复制代码
package main

/*
#cgo LDFLAGS: -L./target/release -lmylib
#include <stdint.h>

extern uint32_t fibonacci(uint32_t n);
extern int32_t process_data(const uint8_t* data, size_t len);
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func main() {
    // 调用Rust的fibonacci函数
    result := C.fibonacci(20)
    fmt.Printf("Fibonacci(20) = %d\n", result)
    
    // 调用Rust的process_data函数
    data := []byte{1, 2, 3, 4, 5}
    sum := C.process_data((*C.uint8_t)(unsafe.Pointer(&data[0])), C.size_t(len(data)))
    fmt.Printf("Sum = %d\n", sum)
}

这样可以在Go项目中利用Rust的性能优势,处理性能关键的部分。

十二、社区与未来发展

Go社区

  • 成熟度:非常成熟,企业采用广泛
  • 学习资源:丰富的中英文资源
  • 就业市场:国内外需求旺盛
  • 发展方向:专注于云原生和微服务领域

Rust社区

  • 成熟度:快速发展中,越来越多大公司采用
  • 学习资源:官方文档质量极高(The Rust Book)
  • 就业市场:需求增长迅速,但相对Go较少
  • 发展方向:系统编程、WebAssembly、嵌入式、区块链

国内Rust发展

  • 华为、阿里、字节跳动等大厂开始采用Rust
  • Rust中文社区(Rust.cc)活跃度提升
  • 越来越多的开源项目使用Rust

十三、性能优化实践

Go性能优化

go 复制代码
package main

import (
    "sync"
    "testing"
)

// 使用sync.Pool减少内存分配
var bufferPool = sync.Pool{
    New: func() interface{} {
        return make([]byte, 1024)
    },
}

func processWithPool() {
    buffer := bufferPool.Get().([]byte)
    defer bufferPool.Put(buffer)
    
    // 使用buffer
}

// 使用strings.Builder高效拼接字符串
func buildString(parts []string) string {
    var builder strings.Builder
    for _, part := range parts {
        builder.WriteString(part)
    }
    return builder.String()
}

Rust性能优化

rust 复制代码
// 使用迭代器避免不必要的分配
fn sum_even_numbers(numbers: &[i32]) -> i32 {
    numbers
        .iter()
        .filter(|&&x| x % 2 == 0)
        .sum()
}

// 使用Cow避免不必要的克隆
use std::borrow::Cow;

fn process_string(input: &str) -> Cow<str> {
    if input.contains("bad") {
        Cow::Owned(input.replace("bad", "good"))
    } else {
        Cow::Borrowed(input)
    }
}

// 使用inline优化小函数
#[inline]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

十四、测试对比

Go测试

go 复制代码
package main

import "testing"

func Add(a, b int) int {
    return a + b
}

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"negative numbers", -2, -3, -5},
        {"mixed numbers", -2, 3, 1},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d", 
                    tt.a, tt.b, result, tt.expected)
            }
        })
    }
}

// 基准测试
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(10, 20)
    }
}

Rust测试

rust 复制代码
fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_add_positive() {
        assert_eq!(add(2, 3), 5);
    }
    
    #[test]
    fn test_add_negative() {
        assert_eq!(add(-2, -3), -5);
    }
    
    #[test]
    fn test_add_mixed() {
        assert_eq!(add(-2, 3), 1);
    }
    
    // 参数化测试
    #[test]
    fn test_add_various() {
        let test_cases = vec![
            (2, 3, 5),
            (-2, -3, -5),
            (-2, 3, 1),
        ];
        
        for (a, b, expected) in test_cases {
            assert_eq!(add(a, b), expected);
        }
    }
}

// 基准测试(需要nightly版本或criterion库)
#[cfg(test)]
mod benches {
    use super::*;
    use criterion::{black_box, criterion_group, criterion_main, Criterion};
    
    fn bench_add(c: &mut Criterion) {
        c.bench_function("add", |b| {
            b.iter(|| add(black_box(10), black_box(20)))
        });
    }
    
    criterion_group!(benches, bench_add);
    criterion_main!(benches);
}

十五、总结与建议

技术特性对比表

维度 Go Rust 备注
学习曲线 ⭐⭐ ⭐⭐⭐⭐⭐ Go更易学
性能 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ Rust略胜一筹
内存安全 ⭐⭐⭐ ⭐⭐⭐⭐⭐ Rust编译期保证
并发编程 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ Go更简单
开发速度 ⭐⭐⭐⭐⭐ ⭐⭐⭐ Go更快
编译速度 ⭐⭐⭐⭐⭐ ⭐⭐ Go显著更快
生态成熟度 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ Go更成熟
跨平台能力 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ Rust支持更广

给Rust初学者的建议

  1. 不要被编译器吓倒:与编译器"搏斗"是学习过程的一部分,它在教你写更安全的代码。
  2. 循序渐进
    • 第一周:基础语法、所有权基本概念
    • 第二周:借用和生命周期
    • 第三周:trait和泛型
    • 第四周:错误处理和常用库
    • 第五周:异步编程
  3. 推荐资源
    • 《The Rust Programming Language》(官方书籍,有中文版)
    • Rustlings(交互式练习)
    • Rust by Example(示例学习)
    • 《Rust语言圣经》(国内社区出品)
  4. 实践项目
    • 命令行工具(使用clap)
    • Web API(使用actix-web或axum)
    • 简单的数据库封装
    • 小型游戏或模拟器

结语

Rust和Go都是优秀的现代编程语言,它们代表了不同的设计哲学和技术取舍。Go追求简单和生产力,Rust追求安全和性能。选择哪个语言,取决于你的具体需求、团队情况和项目特点。

对于国内开发者而言,Rust正在快速发展,越来越多的企业开始采用。学习Rust不仅能提升个人技术能力,还能为未来的职业发展打开新的可能。同时,Go的生态成熟度和易用性使其成为当前后端开发的热门选择。

我的建议是:如果时间允许,两者都值得学习。 它们会让你从不同角度理解编程语言的设计,成为更全面的工程师。

相关推荐
星释2 小时前
Rust 练习册 :Macros与宏系统
开发语言·后端·rust
l1t2 小时前
利用短整数类型和部分字符串优化DuckDB利用数组求解数独SQL
开发语言·数据库·sql·duckdb
权泽谦3 小时前
从零搭建一个 PHP 登录注册系统(含完整源码)
android·开发语言·php
林太白3 小时前
rust18-通知管理模块
后端·rust
PieroPc3 小时前
用python Streamlit 做个RapidOCR 文本识别系统
开发语言·python·ocr
暖木生晖3 小时前
Javascript函数之匿名函数以及立即执行函数的使用方法?
开发语言·javascript·ecmascript
say_fall3 小时前
C语言容易被忽略的易错点(2)
c语言·开发语言
syker3 小时前
NEWBASIC 2.06.7 API 帮助与用户使用手册
开发语言·人工智能·机器学习·自动化
Js_cold3 小时前
Verilog运算符
开发语言·fpga开发·verilog