TheMatrix 写了: 2025年 4月 29日 17:34
这两天在玩Rust。不容易。我主要是没有C++的基础,什么unique_ptr,shared_ptr,都是我不玩C++以后才出来的。没用过。Rust看起来很多概念就是为了实现这两个smart pointer。
发现强类型一个不好的地方:就是对高阶函数不友好。因为函数的类型是很长的,比如:
fn (Vec<String>, Vec<String>) --> Vec<String>
这就是一个二元函数的类型声明。这还只是一个一阶函数,二阶函数就更长了。所以不友好。
Rust里面函数类型还有变体,什么Box,dyn,为了实现closure。我觉得概念不是很直接。closure应该和对应的函数是同一个类型,我觉得这样才直接。不能实现的话,是不是说明还没有设计完美?python里面似乎不用区分closure和函数。
终于把python写的SQL parser port到Rust了。绝对的wrestling,战了好几天。
use std::any::Any;
use once_cell::sync::Lazy;
use std::sync::{Arc, Mutex};
type State = u32;
type Token = (String, String);
type Data = Vec<Arc<dyn Any + Send + Sync>>;
type BNF = Arc<dyn Fn(State) -> (State, Data) + Send + Sync>;
type PostProcessor = Arc<dyn Fn((State, Data)) -> (State, Data) + Send + Sync>;
type GoodChecker = Arc<dyn Fn(&Data) -> bool + Send + Sync>;
static TOKENS: Lazy<Mutex<Data>> = Lazy::new(|| Mutex::new(vec![]));
这个类型声明,没有chatgpt我是搞不定。
有了chatgpt,递归那里也是怎么都调不通。我以为是死循环,后来发现可能是Mutex递归lock住了。现在我也没明白是怎么回事。
还有一个generic的版本:
use once_cell::sync::Lazy;
use std::sync::{Arc, Mutex};
type State = u32;
type Token = (String, String);
type BNF<T> = Arc<dyn Fn(State) -> (State, Vec<T>) + Send + Sync>;
type PostProcessor<T> = Arc<dyn Fn((State, Vec<T>)) -> (State, Vec<T>) + Send + Sync>;
type GoodChecker<T> = Arc<dyn Fn(&Vec<T>) -> bool + Send + Sync>;
static CHARS: Lazy<Mutex<Vec<char>>> = Lazy::new(|| Mutex::new(vec![]));
static TOKENS: Lazy<Mutex<Vec<Token>>> = Lazy::new(|| Mutex::new(vec![]));