是否可以从字符串生成 Rust 宏中的符号或标识符?或者对标识符执行类似字符串的操作?
我想生成一个给定符号的方法,但需要将其小写以获取方法名称。
get!(B);
// should expand to
fn b() -> B {
// method body
}
Run Code Online (Sandbox Code Playgroud)
很容易接近...
macro_rules! get {
($kind:ident, $method:ident)
=>
{
fn $method() -> $kind {
// method body
}
}
}
get!(B, b)
Run Code Online (Sandbox Code Playgroud)
但是很不满意。
此代码无法编译:
fn ref_on_int<T>(_: T) where T: AsRef<i32> {}
fn main() {
ref_on_int(&0_i32)
}
Run Code Online (Sandbox Code Playgroud)
因为
fn ref_on_int<T>(_: T) where T: AsRef<i32> {}
fn main() {
ref_on_int(&0_i32)
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
这可能对例如像这样的新类型很有用
struct MyInt(i32);
impl AsRef<i32> for MyInt {
/* etc. */
}
Run Code Online (Sandbox Code Playgroud)
那么您可以无差别地传递 an 上i32
的引用或 a 上的引用MyInt
,因为在这两种情况下我们都有一个i32
.
我们可以实现traits core::ops
来定义我们类型的运算符的行为.特征本身用#[lang =...]
属性注释,因此编译器知道哪些特征和操作符属于一起.
例如,Add
基本类型的实现看起来像这样(宏从这里手动扩展和简化):
impl Add for i32 {
type Output = i32;
fn add(self, other: i32) -> i32 {
self + other
}
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,该实现在+
内部使用运算符,可能会调用self.add(other)
,从而导致无限递归.显然,事情不会发生这种情况,因为像3 + 4
(假设没有不断的折叠)这样的表达式可以完美地运行.
现在考虑这个特性的天真实现Add
:
use std::ops::Add;
struct Foo;
impl Add for Foo {
type Output = Foo;
fn add(self, other: Foo) -> Foo {
self + other
}
}
fn main() {
let two_foo = Foo + Foo;
}
Run Code Online (Sandbox Code Playgroud)
编译器警告 …
我不能在不使用闭包的情况下编译它.我试图让函数apply
首先返回正确的闭包.
#![feature(conservative_impl_trait)]
#![allow(dead_code)]
fn accumulate<'a>(tuples: &[(&'a str, &Fn(i32) -> bool)], i: i32) {
// this works
let _ = tuples.iter().filter(|t| apply(second, i)(t));
// this doesn't
//let f = apply(second, i);
//let _ = tuples.iter().filter(f);
//this works as well
let f = |t: &&(_,_)| apply(second, i)(t);
let _ = tuples.iter().filter(f);
}
fn apply<A, B, C, F, G>(mut f: F, a: A) -> impl FnMut(B) -> C
where F: FnMut(B) -> G,
G: FnMut(A) -> C,
A: Clone
{
move …
Run Code Online (Sandbox Code Playgroud) 我有以下代码使用Rc
和Box
; 那些有什么区别?哪一个更好?
use std::rc::Rc;
fn main() {
let a = Box::new(1);
let a1 = &a;
let a2 = &a;
let b = Rc::new(1);
let b1 = b.clone();
let b2 = b.clone();
println!("{} {}", a1, a2);
println!("{} {}", b1, b2);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用Command
API 启动进程并将其标准输出重定向到标准错误.以下失败:
Command::new("tput").arg("rc")
.stdout(io::stderr())
.status()
.expect("failed to run tput");
Run Code Online (Sandbox Code Playgroud)
因为Command::new("tput").arg("rc").stdout(<XXX>)
期望std::process::Stdio
:
expected struct `std::process::Stdio`, found struct `std::io::Stderr`
Run Code Online (Sandbox Code Playgroud)
Bash中的等价物可能是tput rc > /dev/stderr
.
我想知道如何正确地做到这一点.
我想知道为什么PHP中的以下语句返回true?
true>=4
Run Code Online (Sandbox Code Playgroud)
例如,这样的线路将回响 1
echo true>=4;
Run Code Online (Sandbox Code Playgroud)
任何人都能解释一下这背后的逻辑吗?
我希望能够获得对引用(包括可变和不可变)usize
裹Bar
在Foo
枚举:
use Foo::*;
#[derive(Debug, PartialEq, Clone)]
pub enum Foo {
Bar(usize)
}
impl Foo {
/* this works */
fn get_bar_ref(&self) -> &usize {
match *self {
Bar(ref n) => &n
}
}
/* this doesn't */
fn get_bar_ref_mut(&mut self) -> &mut usize {
match *self {
Bar(ref mut n) => &mut n
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我无法获得可变参考,因为:
n
活得不够久
我能提供的访问的其他内容类似的功能这两个变种Foo
被Box
艾德-为何可变借(为什么只有它)失败,未装箱原始?
我想使用Haskell函数
readFile :: FilePath -> IO String
Run Code Online (Sandbox Code Playgroud)
将文件的内容读入字符串.在文档中,我读到"文件是按需读取的,与getContents一样."
我不确定我完全理解这一点.例如,假设我写
s <- readFile "t.txt"
Run Code Online (Sandbox Code Playgroud)
执行此操作时:
length s
所有内容将被读取并且文件将被关闭).readFile
就会关闭与此调用相关联的文件句柄(自动).我的第三个陈述是否正确?那么,我可以在readFile
不关闭文件句柄的情况下调用吗?只要我没有消耗(访问)整个结果字符串,句柄是否会保持打开状态?
编辑
以下是有关我的疑虑的更多信息.假设我有以下内容:
foo :: String -> IO String
foo filename = do
s <- readFile "t.txt"
putStrLn "File has been read."
return s
Run Code Online (Sandbox Code Playgroud)
当putStrLn
执行时,我会(直觉地)期望
s
包含文件的全部内容t.txt
,如果不是这样的话:
s
时候putStrLn
执行包含什么?putStrLn
执行时文件句柄处于什么状态?putStrLn
执行的时间s
不包含文件的全部内容,实际上何时会读取此内容,何时关闭文件?从阅读此页面,它表明您需要关闭所有默认值以覆盖它们.
除该
default
功能外,所有功能均可选择加入.要选择退出默认功能,请使用default-features = false
和挑选各个功能.
我使用的其他构建系统(CMake,SCons,Autotools,Jam)都允许更改单个默认值.
这可能与货物有关吗?
这很有用,因为在大多数情况下,我想使用默认选项,只需稍作调整.它也对我很重要,在未来 - 的新特性,开发者认为应该默认启用,未在我的构建,因为我选择了调整无关的功能被禁用.
编辑:已打开有关此功能的问题.