我可以使用“空指针优化"吗?对于我自己的非指针类型? [英] Can I use the "null pointer optimization" for my own non-pointer types?

查看:92
本文介绍了我可以使用“空指针优化"吗?对于我自己的非指针类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您拥有Option<&T>时,编译器会知道NULL永远不是&T的可能值,并且对代码进行编码将None变体替换为NULL .这样可以节省空间:

When you have an Option<&T>, the compiler knows that NULL is never a possible value for &T, and encodes the None variant as NULL instead. This allows for space-saving:

use std::mem;

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

但是,如果对非指针类型执行相同的操作,则不需要额外的位来存储该值,并且需要额外的空间:

However, if you do the same with a non-pointer type, there's no extra bits to store that value in and extra space is required:

use std::mem;

fn main() {
    // fails because left is 1 and right is 2
    assert_eq!(mem::size_of::<u8>(), mem::size_of::<Option<u8>>()); 
}

通常,这是正确的.但是,我想选择优化,因为我知道我的类型具有某些不可能的值.举例来说,我可能有一个具有年龄的玩家角色.年龄可能未知,但永远不会达到255:

In general, this is correct. However, I'd like to opt-in to the optimization because I know that my type has certain impossible values. As a made-up-example, I might have a player character that has an age. The age may be unknown, but will never be as high as 255:

struct Age(u8);

struct Player {
    age: Option<Age>,
}

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

I'd like to be able to inform the optimizer of this constraint - Age can never be 255, so it's safe to use that bit pattern as None. Is this possible?

推荐答案

从Rust 1.28开始,您可以使用

As of Rust 1.28, you can use std::num::NonZeroU8 (and friends). This acts as a wrapper that tells the compiler the contents of a number will never contain a literal zero. It's also why Option<Box<T>> is pointer-sized.

这是一个示例,显示了如何创建Age并读取其有效载荷.

Here's an example showing how to create an Age and read its payload.

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
}

这篇关于我可以使用“空指针优化"吗?对于我自己的非指针类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆