我试图实现IntoIterator
的[T; N]
.我用Default
和swap
(PlayPen)写了一个完全安全的版本.然后,我把它移植使用uninitialized
,ptr::copy
,Drop
和forget
(围栏).我的Iterator结构如下所示:
struct IntoIter<T> {
inner: Option<[T; N]>,
i: usize,
}
impl<T> Iterator for IntoIter<T> { ... }
Run Code Online (Sandbox Code Playgroud)
由于我不想为每个值创建一个Iterator结构N
,我将结构更改为
struct IntoIter<U> {
inner: Option<U>,
i: usize,
}
impl<T> Iterator for IntoIter<[T; N]> { ... }
Run Code Online (Sandbox Code Playgroud)
显然我必须调整Iterator
和Drop
实现(PlayPen).
但现在我以某种方式介绍了未定义的行为.根据println
s,优化水平或黄道标志发生或不发生恐慌.
thread '<main>' panicked at 'index out of bounds: the len is 5 but …
Run Code Online (Sandbox Code Playgroud) 这段代码:
use std::fmt;
use std::result::Result::{self, Ok, Err};
#[derive(Clone)]
#[derive(Copy)]
enum Tile {
White,
Black,
Empty
}
type Board = &[[Tile; 19]; 19];
Run Code Online (Sandbox Code Playgroud)
产生此错误:
Compiling go v0.1.0 (file:///home/max/gits/go_rusty)
src/main.rs:12:14: 12:31 error: missing lifetime specifier [E0106]
src/main.rs:12 type Board = &[[Tile; 19]; 19];
^~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `go`.
To learn more, run the command again with --verbose.
Run Code Online (Sandbox Code Playgroud)
我很难找到任何解释生命周期说明符是什么以及为什么我需要在类型别名声明上.
我们有两个特点A
,B
为此
B
所有实现的类型A
.A
对任何类型实现的引用A
.B
对任何类型实现的引用B
.实际上,所有三个都会导致冲突,因为现在对实现的类型的引用A
会有两个实现B
.一个由于一个impl<T: A> A for &T
和一个传递性由于impl<T: A> B for T
(然后是impl<T: B> B for &T
.
我无法删除impl<T: B> B for &T
,因为可能有类型实现B
但不是A
这是展示行为的示例代码.
trait A {}
trait B {}
impl<'a, T: A> A for &'a T {}
impl<T: A> B for T {}
impl<'a, T: B> B for &'a …
Run Code Online (Sandbox Code Playgroud) 模式匹配一个Vec<T>
可以通过使用来完成&v[..]
或v.as_slice()
.
let x = vec![1, 2, 3];
match &x[..] {
[] => println!("empty"),
[_] => println!("one"),
[..] => println!("many"),
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个包含Vec
我要匹配的字段的枚举,我需要在外部匹配臂内创建一个嵌套匹配:
enum Test {
Many(Vec<u8>),
Text(String),
}
fn main() {
let x = Test::Many(vec![1, 2, 3]);
match x {
Test::Text(s) => println!("{}", s),
Test::Many(v) => match &v[..] {
[] => println!("empty"),
[_] => println!("one"),
[..] => println!("many"),
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是直接匹配Vec
以下示例中的as:
match x {
Test::Text(s) => println!("{}", s),
Test::Many([]) => …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用特征和相关类型在Rust上实现一些东西.我不确定如何用文字形成我的问题,所以我将添加一个代码片段,希望能说明我正在尝试做什么.
pub trait Person {}
pub trait Directory<P: Person> {
type Per = P;
fn get_person(&self) -> Self::Per;
}
pub trait Catalog {
type Per : Person;
type Dir : Directory<Self::Per>;
fn get_directory(&self) -> Self::Dir;
}
fn do_something<C>(catalog: C) where C: Catalog {
let directory : C::Dir = catalog.get_directory();
// let person : C::Per = directory.get_person();
// The code above fails with:
// error: mismatched types:
// expected `<C as Catalog>::Per`,
// found `<<C as Catalog>::Dir as Directory<<C as Catalog>::Per>>::Per` …
Run Code Online (Sandbox Code Playgroud) 我正在学习Rust并试图立即编写一个简单的标记器.我想通过一个字符串来运行每个正则表达式对着字符串中的当前位置,创建一个标记,然后向前跳过并重复,直到我处理完整个字符串.我知道我可以将它们放入更大的正则表达式并循环捕获,但我需要单独处理它们以进行域解析.
但是,我在正则表达式框中看不到允许偏移,所以我可以在特定点再次开始匹配.
extern crate regex;
use regex::Regex;
fn main() {
let input = "3 + foo/4";
let ident_re = Regex::new("[a-zA-Z][a-zA-Z0-9]*").unwrap();
let number_re = Regex::new("[1-9][0-9]*").unwrap();
let ops_re = Regex::new(r"[+-*/]").unwrap();
let ws_re = Regex::new(r"[ \t\n\r]*").unwrap();
let mut i: usize = 0;
while i < input.len() {
// Here check each regex to see if a match starting at input[i]
// if so copy the match and increment i by length of match.
}
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找的那些正则表达式实际上也会在运行时变化.有时候我可能只会寻找其中的一些,而其他人(在顶级)我可能会寻找几乎所有这些.
我们有一个不可复制的类型和一个特征:
struct Struct;
trait Trait {}
impl Trait for Struct {}
Run Code Online (Sandbox Code Playgroud)
如果我们创建 a&Struct
并取消引用它,我们会得到一个右值引用,我们可以用它来初始化一个 by-ref 绑定:
let a: &Struct = &Struct;
let ref a: Struct = *a;
Run Code Online (Sandbox Code Playgroud)
我们也可以通过 ref 绑定直接初始化它:
let ref a: Struct = Struct;
Run Code Online (Sandbox Code Playgroud)
但是如果我们声明我们的变量绑定需要引用,只有第一个代码片段有效
let a: &Trait = &Struct;
let ref a: Trait = *a;
Run Code Online (Sandbox Code Playgroud)
尝试直接执行此操作
let ref a: Trait = Struct;
Run Code Online (Sandbox Code Playgroud)
或者通过循环
let a: &Struct = &Struct;
let ref a: Trait = *a;
Run Code Online (Sandbox Code Playgroud)
或者
let ref a: Trait = *&Struct;
Run Code Online (Sandbox Code Playgroud)
会给我们一个mismatched types
错误。显然它们不是同一类型,但推理适用于引用。
这是根本没有实现(还没有?)还是有更深层次的原因被禁止?
当库(例如Boost)使用模板(泛型)时,是否可以使用Rust的C++库?
我是Rust的新手.作为一个学习练习,我正在尝试制作一个基本的二叉树.这是我到目前为止:
fn main() {
let data = vec![6,1,2,3,4,5];
let mut root = Node::<i32> { value: data[0], left: None, right: None };
for val in data {
createAndInsert::<i32>(&root, val);
}
println!("Root value: {}", root.value);
}
fn createAndInsert<T: PartialOrd>(mut root: &Node<T>, value: T) {
let mut n = Node::<T> { value: value, left: None, right: None };
insert::<T>(&root, &n);
}
fn insert<T: PartialOrd>(mut curr: &Node<T>, new: &Node<T>) {
if new.value > curr.value {
match curr.right {
Some(ref n) => insert(n, new),
None …
Run Code Online (Sandbox Code Playgroud) 考虑下面的代码,我将每个线程附加到Vector,以便在我生成每个线程之后将它们连接到主线程,但是我无法调用iter()
JoinHandlers的向量.
我该怎么做呢?
fn main() {
let requests = Arc::new(Mutex::new(Vec::new()));
let threads = Arc::new(Mutex::new(Vec::new()));
for _x in 0..100 {
println!("Spawning thread: {}", _x);
let mut client = Client::new();
let thread_items = requests.clone();
let handle = thread::spawn(move || {
for _y in 0..100 {
println!("Firing requests: {}", _y);
let start = time::precise_time_s();
let _res = client.get("http://jacob.uk.com")
.header(Connection::close())
.send().unwrap();
let end = time::precise_time_s();
thread_items.lock().unwrap().push((Request::new(end-start)));
}
});
threads.lock().unwrap().push((handle));
}
// src/main.rs:53:22: 53:30 error: type `alloc::arc::Arc<std::sync::mutex::Mutex<collections::vec::Vec<std::thread::JoinHandle<()>>>>` does not implement any method in scope …
Run Code Online (Sandbox Code Playgroud)