系统编程语言,如C++和Rust,迫使程序员处理对象和引用之间的区别。这种区别使我们能够编写出惊人的快速代码,但代价很高:这是一个永无止境的bug来源。如果程序的其他部分引用对象,那么修改对象的内容几乎总是一个错误。有多种方法可以解决此问题:let x = f("a very long string".to_string());
let y = g("a very long string".to_string());
// …let s = "a very long string".to_string();
let x = f(s);
let y = g(s);let s = "a very long string".to_string();
f(s.clone());
g(s);h(s) 。
let s = "a very long string".to_string();
f(s.clone());
g(s);
// fifty lines of code...
h(s); // ← won’t compile, you need scroll up and update g(s).// Do we have to type "MyType::from" every time?
// How about introducing an alias?
let x = MyType::from(b"bytes");
let y = MyType::from("string");
// Nope, Rust won't let us.
let f = MyType::from;
let x = f(b"bytes");
let y = f("string");
// - ^^^^^^^^ expected slice `[u8]`, found `str`
// |
// arguments to this function are incorrect// Compiles fine, but is longer than the original.
fn f<T: Into<MyType>>(t: T) -> MyType { t.into() }
let x = f(b"bytes");
let y = f("string");impl State {
fn tick(&mut self) {
self.state = match self.state {
Ping(s) => { self.x += 1; Pong(s) }
Pong(s) => { self.x += 1; Ping(s) }
}
}
}impl State {
fn tick(&mut self) {
self.state = match self.state {
Ping(s) => { self.inc(); Pong(s) } // ← compile error
Pong(s) => { self.inc(); Ping(s) } // ← compile error
}
}
fn inc(&mut self) {
self.x += 1;
}
}struct S { map: HashMap<i64, String>, def: String }
impl S {
fn ensure_has_entry(&mut self, key: i64) {
// Doesn't compile with Rust 2018:
self.map.entry(key).or_insert_with(|| self.def.clone());
// | ------ -------------- ^^ ---- second borrow occurs...
// | | | |
// | | | immutable borrow occurs here
// | | mutable borrow later used by call
// | mutable borrow occurs here
}
}struct S { map: HashMap<i64, String>, def: String }
impl S {
fn ensure_has_entry(&mut self, key: i64) {
use std::collections::hash_map::Entry::*;
// This version is more verbose, but it works with Rust 2018.
match self.map.entry(key) {
Occupied(mut e) => e.get_mut(),
Vacant(mut e) => e.insert(self.def.clone()),
};
}
}struct Hex(Vec<u8>);
impl std::fmt::Display for Hex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.iter().try_for_each(|b| write!(f, "{:02x}", b))
}
}
println!("{}", Hex((0..32).collect()));
// => 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1ffn complex_function(bytes: &Vec<u8>) {
// … a lot of code …
println!("{}", &Hex(bytes)); // That does not work.
println!("{}", Hex(bytes.clone())); // That works but is slow.
// … a lot of code …
}/// A WebAssembly global along with its export specification.
/// The lifetime parameter exists to support zero-copy deserialization
/// for the `&str` fields at the leaves of the structure.
/// For a variant with owned types at the leaves, see `OwnedGlobalSpec`.
pub struct GlobalSpec<'a> {
global: Global<'a>,
export_names: Vec<&'a str>,
}
…
/// A variant of `GlobalSpec` with owned strings throughout.
/// This type is useful when directly building up a value to be serialized.
pub struct OwnedGlobalSpec {
global: OwnedGlobal,
export_names: Vec<String>,
}struct Db { /* … */ }
struct Snapshot<'a> { /* … */ }
impl Db { fn snapshot<'a>(&'a self) -> Snapshot<'a>; }// There is no way to define the following struct without
// contaminating it with lifetimes.
struct DbSnapshot {
snapshot: Snapshot<'a>, // what should 'a be?
db: Arc<Db>,
}let x = vec!["a".to_string(), "b".to_string()];
match x {
// - help: consider slicing here: `x[..]`
["a", "b"] => println!("OK"),
// ^^^^^^^^^^ pattern cannot match with input type `Vec<String>`
_ => (),
}let x = vec!["a".to_string(), "b".to_string()];
match x[..] {
// ----- this expression has type `[String]`
["a", "b"] => println!("OK"),
// ^^^ expected struct `String`, found `&str`
_ => (),
}let x = vec!["a".to_string(), "b".to_string()];
// We have to allocate new storage.
let x_for_match: Vec<_> = x.iter().map(|s| s.as_str()).collect();
match &x_for_match[..] {
["a", "b"] => println!("OK"), // this compiles
_ => (),
}
Forget about balancing Red-Black trees in five lines of code in Rust
这些规则使编译器很容易保证一致性,这是一种聪明的方式,可以说程序的所有部分都看到特定类型的相同特性实现。作为交换,这一规则使整合无关库中的特征和类型变得非常复杂。一个例子是我们只想在测试中使用的特性,例如proptest包中的任意特性。如果编译器从我们的包中派生类型的实现,我们可以节省很多类型,但我们希望我们的生产代码独立于proptest包。在完美的设置中,所有的任意实现都将进入一个单独的仅测试包。不幸的是,孤儿规则反对这种安排,迫使我们咬紧牙关,手动编写proptest策略。在孤立规则下,类型转换特性(如From和Into)也存在问题。我经常看到xxx类型的包开始很小,但最终成为编译链中的瓶颈。将这样的包拆分成更小的部分通常是令人畏惧的,因为复杂的类型转换网络将遥远的类型连接在一起。孤立规则不允许我们在模块边界上切割这些包,并将所有转换移动到一个单独的包中,而不需要做大量乏味的工作。不要误会:孤立规则是一个默认原则。Haskell允许您定义孤立实例,但程序员不赞成这种做法。让我难过的是无法逃脱孤儿规则。在大型代码库中,将大型包分解为较小的部分并维护浅依赖关系图是获得可接受编译速度的唯一途径。孤立规则通常会妨碍修剪依赖关系图。impl Service {
pub fn do_something(&self) {
let guard = self.lock.read();
// …
self.helper_function(); // BUG: will panic or deadlock
// …
}
fn helper_function(&self) {
let guard = self.lock.read();
// …
}
}fn innocently_looking_function() {
tokio::spawn(some_async_func());
// ^
// |
// This code will panic if we remove this line. Spukhafte Fernwirkung!
} // |
// |
fn main() { // v
let _rt = tokio::runtime::Runtime::new().unwrap();
innocently_looking_function();
}三大公有云厂商,香港地区主机测评一、ping时延比对(厦门电信本地测试):Ping时延测试腾讯云阿里云华为云延迟率最低时延44ms,最高72ms,平均46ms47.242段:最低时延59ms,最高204ms,平均107ms最低时延45ms,最高93ms,平均47ms丢包率丢包率小有的ip段丢包率较大每个段都会有概率丢包阿里云:47.242段:最低时延59ms,最高204ms,平均107ms,有的ip段丢包率较大8.210段:最低时延64ms,最高232ms,平均119ms,丢包率较好腾讯云:最低时延44ms,最高72ms,平均46ms,丢包率小华为云:最低时延45ms,最高93ms,平均47m
我想将String传递给Rust库,但它总是会抛出段错误。代码如下://lib.rs#[no_mangle]pubexternfnprocess(foo:String)->String{foo}还有Ruby文件:#embed.rbrequire'ffi'moduleHelloextendFFI::Libraryffi_lib'target/release/libembed.dylib'attach_function:process,[:string],:stringendputsHello.process("foo") 最佳答案 免
我正在尝试将Ruby中的字符串传递给Rust可执行文件,对其进行操作并将操作后的字符串传回。到目前为止,我可以传入字符串并返回它,但我不知道如何将它转换为使用rust字符串,对其进行操作,然后将其传回ruby。这是我目前所拥有的://lib.rsusestd::ffi::CStr;#[no_mangle]pubexternfnreturn_string(test_str:&CStr)->&CStr{//workingfuncitontest_str}#[no_mangle]pubexternfnmanipulate_and_return_string(mystr:&CStr)->&
声明**本文档不做任何商业用途,是作者个人与团队的学习数据结构的心得笔记以及在考研备考中的学习回顾,加以整理,仅用于学习交流,任何人不得进行有偿销售、本文档的著作权归作者或团队所有,文中部分引用的图片说明来源,特此感谢。任何人使用本文档所述内容所衍生的风险与责任均由其自行承担,本文档的作者或团队不承担任何因此产生的直接或间接损失或责任。同时,本文档的内容仅代表作者或团队的观点和理解,并不代表其他任何组织或个人的观点和立场。读者在阅读和使用本文档时,请自行判断其内容的正确性、准确性和实用性,十分欢迎读者批评指正、提出建议意见,不足之处,多多包涵。**团队微信公众号:CodeLab代码实验室作者C
我有这个简单的Rust函数:#[no_mangle]pubfncompute(operator:&str,n1:i32,n2:i32)->i32{matchoperator{"SUM"=>n1+n2,"DIFF"=>n1-n2,"MULT"=>n1*n2,"DIV"=>n1/n2,_=>0}}我正在成功地将其编译为WebAssembly,但无法将operator参数从JS传递给Rust。调用Rust函数的JS行如下所示:instance.exports.compute(operator,n1,n2);operator是一个JSString和n1,n2是JSNumbern1和n2被正确传
我编写了一个基准测试来计算前10000个素数的总和,并将Rust与JavaScript进行了比较。NodeJS上的JavaScript是Rust、Scala和Java中最快的。尽管这些程序有意使用函数式风格来测试素数以展示Rust的零成本抽象的优势,但NodeJS击败了它们。NodeJS这种动态类型运行时怎么能这么快?Rust代码fnsum_primes(n:usize)->u64{letmutprimes=Vec::new();letmutcurrent:u64=2;letmutsum:u64=0;whileprimes.len()JavaScript代码functionsumPri
1、下载安装包下载地址:InstallRust-RustProgrammingLanguageAlanguageempoweringeveryonetobuildreliableandefficientsoftware.https://www.rust-lang.org/tools/install 运行之后我们发现,会默认安装在C盘。 2、在需要安装的目录下分别建两个文件夹,名为.cargo与.rustup3、配置环境变量右键此电脑->属性->高级系统设置->环境变量编辑"Path"变量,新增"%RUSTUP_HOME%"与"%CARGO_HOME%" 4、开始安装Rust这时候我们重新运行R
我有两个(等效的?)程序,一个在Go中,另一个在Rust中。平均执行时间为:开始~169ms使用rust~201ms开始packagemainimport("fmt""time")funcmain(){work:=[]float64{0.00,1.00}start:=time.Now()fori:=0;i使用rust我用--release编译usestd::time::Instant;fnmain(){letmutwork:Vec=Vec::new();work.push(0.00);work.push(1.00);letnow=Instant::now();for_xin1..100
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭3年前。Improvethisquestion我阅读了一些关于Go的GC的堆栈溢出信息。Go垃圾收集器中的栈和堆模型我想知道如果一个变量需要在Go中定义在堆或栈中,然后GC要收集它,使用什么算法?如果我们假设在具有GC的语言中,堆更高效,那么Rust又如何?与Go相比,Rust如何处理这个问题?特别是关于Go中的引用计数器,我们在大多数时候别无选择地询问编译器,但这样的工具存在并且它以自己的方式完成它的工作!我读过这个:Stackvsheap
我在Rust中有以下代码:fnmain(){letmutsum=0is;foriin(0is..100000000is){sum=sum+i;}println!("{}",sum);}结果,我有4999999950000000但是,当我尝试使用Golang和Ruby检查此代码时-我看到了另一个结果golang版本:packagemainimport"fmt"funcmain(){varsum=0fori:=1;iruby版本:@sum=0(1...99999999).eachdo|i|@sum+=iendputs@sumRuby和Golang的结果都是4999999850000001P