Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization 我能用“我能用”吗;“空指针优化”;对于我自己的非指针类型?_Optimization_Rust - Fatal编程技术网

Optimization 我能用“我能用”吗;“空指针优化”;对于我自己的非指针类型?

Optimization 我能用“我能用”吗;“空指针优化”;对于我自己的非指针类型?,optimization,rust,Optimization,Rust,当您有选项时,编译器知道NULL永远不是&T的可能值,并且。这样可以节省空间: use std::mem; fn main() { assert_eq!(mem::size_of::<&u8>(), mem::size_of::<Option<&u8>>()); } 我希望能够通知优化器此约束-Age永远不能是255,因此将该位模式用作None是安全的。这可能吗?从Rust 1.28开始,您可以使用(和朋友)。这就像一个包装器,告诉

当您有
选项时
,编译器知道
NULL
永远不是
&T
的可能值,并且。这样可以节省空间:

use std::mem;

fn main() {
    assert_eq!(mem::size_of::<&u8>(), mem::size_of::<Option<&u8>>());
}

我希望能够通知优化器此约束-
Age
永远不能是
255
,因此将该位模式用作
None
是安全的。这可能吗?

从Rust 1.28开始,您可以使用(和朋友)。这就像一个包装器,告诉编译器数字的内容永远不会包含文字零。这也是
选项
为指针大小的原因

下面的示例演示了如何创建
Age
并读取其有效负载

use std::num::NonZeroU8;

struct Age(NonZeroU8);

impl Age {
    pub fn new(age: u8) -> Age {
        let age = NonZeroU8::new(age).expect("Age cannot be zero!");
        Age(age)
    }

    pub fn age(&self) -> u8 {
        self.0.get()
    }
}

struct Player {
    age: Option<Age>,
}

fn main() {
    println!("size: {}", std::mem::size_of::<Player>());
    // Output: size: 1
}
使用std::num::NonZeroU8;
结构年龄(非零U8);
植入年龄{
新发布(年龄:u8)->age{
让age=NonZeroU8::new(age).expect(“age不能为零!”);
年龄
}
发布fn年龄和自我)->u8{
self.0.get()
}
}
结构播放器{
年龄:选择,
}
fn main(){
println!((“大小:{}”,std::mem::size_of::());
//输出:大小:1
}

根据名称,我假设
非零值
不允许零值。除了零以外的值呢?在我的例子中,零可能是有效的,但255不是。@Shepmaster:它被硬编码为非0,我想通过特征和相关常数可以扩展它。。。不过现在你只能满足于数学了。如果255是您的魔法值,那么将
+1
应用到存储器和来自存储器的
-1
(使用包装算法)将足以让
非零
魔法工作:)@MatthieuM。当然,我只需要做更多的分析,看看它是否真的值得。使用更少的字节似乎是一个明显的胜利;“到处使用更少的字节和强制数学就不那么可靠了。”@Shepmaster:当然;虽然0是一个经常使用的魔法值,但很多分支指令都是专门针对它的(
jz
jnz
),因此不清楚相关的常数是否可以超过它。顺便说一句,非零u*
将稳定在1.28。
struct Age(u8);

struct Player {
    age: Option<Age>,
}
use std::num::NonZeroU8;

struct Age(NonZeroU8);

impl Age {
    pub fn new(age: u8) -> Age {
        let age = NonZeroU8::new(age).expect("Age cannot be zero!");
        Age(age)
    }

    pub fn age(&self) -> u8 {
        self.0.get()
    }
}

struct Player {
    age: Option<Age>,
}

fn main() {
    println!("size: {}", std::mem::size_of::<Player>());
    // Output: size: 1
}