我需要将一个结构体视为 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)
这根本不是目的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)
这通常是一个非常糟糕的主意,您很可能不应该这样做。
| 归档时间: |
|
| 查看次数: |
1334 次 |
| 最近记录: |