repr(transparent) 不允许将包含数组的结构视为数组

Nul*_*lik 0 rust

我需要将一个结构体视为 16 个无符号整数的数组,并且传递CreditCard类型将是透明的,因为我将传递 16 个无符号整数的数组。

如何使这段代码按照设计的方式工作?

use std::fmt;
/// Credit Card type
#[repr(transparent)]
pub struct CreditCard([u8; 16]);

impl fmt::Display for CreditCard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{}{}{}{}-{}{}{}{}-{}{}{}{}-{}{}{}{}",
            self[0],
            self[1],
            self[2],
            self[3],
            self[4],
            self[5],
            self[6],
            self[7],
            self[8],
            self[9],
            self[10],
            self[11],
            self[12],
            self[13],
            self[14],
            self[15]
        )
    }
}
fn process_cc(card: CreditCard) {
    // do whatever
    println!("processed CC {}", card);
}
fn main() {
    let cc: CreditCard = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4];
    println!("cc = {}", cc);
    let card_data: [u8; 16] = [1, 2, 3, 4, 2, 2, 2, 2, 9, 8, 7, 6, 5, 5, 5, 5];
    process_cc(card_data);
}
Run Code Online (Sandbox Code Playgroud)

操场

use std::fmt;
/// Credit Card type
#[repr(transparent)]
pub struct CreditCard([u8; 16]);

impl fmt::Display for CreditCard {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "{}{}{}{}-{}{}{}{}-{}{}{}{}-{}{}{}{}",
            self[0],
            self[1],
            self[2],
            self[3],
            self[4],
            self[5],
            self[6],
            self[7],
            self[8],
            self[9],
            self[10],
            self[11],
            self[12],
            self[13],
            self[14],
            self[15]
        )
    }
}
fn process_cc(card: CreditCard) {
    // do whatever
    println!("processed CC {}", card);
}
fn main() {
    let cc: CreditCard = [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4];
    println!("cc = {}", cc);
    let card_data: [u8; 16] = [1, 2, 3, 4, 2, 2, 2, 2, 9, 8, 7, 6, 5, 5, 5, 5];
    process_cc(card_data);
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 5

根本不是目的repr(transparent)。坦率地说,我很困惑你发现了这样一个小众功能却没有阅读它的文档

具有此表示形式的结构具有与单个非零大小字段相同的布局和 ABI。

这与类型在类型系统中的行为方式无关,只与类型值的内存结构有关。

你想要做的事情甚至不属于强类型语言。您不能仅仅将数组分配给另一种类型,因为它是另一种类型repr(transparent)将位从一个位转换为另一个位是有效的,但这永远不会自动发生。

更好的选择是为您的类型实现Deref和:From

use std::ops::Deref;

impl Deref for CreditCard {
    type Target = [u8; 16];

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl From<[u8; 16]> for CreditCard {
    fn from(other: [u8; 16]) -> Self {
        CreditCard(other)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后采用任何可以转换为的类型CreditCard

fn process_cc(card: impl Into<CreditCard>) {
    // do whatever
    println!("processed CC {}", card.into());
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:


如果您执意要使用repr(transparent),则需要执行以下操作:

fn process_cc(card: [u8; 16]) {
    use std::mem;
    let card: CreditCard = unsafe { mem::transmute(card) };
    // do whatever
    println!("processed CC {}", card);
}
Run Code Online (Sandbox Code Playgroud)

这通常是一个非常糟糕的主意,您很可能不应该这样做。