问题描述
考虑一个实现为 @H_502_1@[u8; 2] 的结构。是否可以构造对整个结构的 @H_502_1@&mut u16 可变引用?有安全的方法吗?
作为另一种表述方式,是否有一种实现方式:
@H_502_1@fn ref_all(&mut [u8; 2]) -> &mut u16
有没有办法对自定义类型也这样做?
解决方法
没有完全安全的方法可以做到这一点,但是为切片定义了 align_to_mut
(及其不可变的对应物 Sub SheetsFromTemplate()
Dim wsMaster As Worksheet,wsTemp As Worksheet,wasVisible As Boolean
Dim shNames As Range,Nm As Range,wsEntry As Worksheet,entryName
With ThisWorkbook
Set wsTemp = .Sheets("Template")
wasVisible = (wsTemp.Visible = xlSheetVisible)
If Not wasVisible Then wsTemp.Visible = xlSheetVisible
Set wsMaster = .Sheets("Master")
Set shNames = wsMaster.Range("C4:C" & Rows.Count).SpecialCells(xlConstants)
Application.ScreenUpdating = False
For Each Nm In shNames
entryName = Nm.Text
Set wsEntry = Nothing 'EDIT
On Error Resume Next 'ignore error if no sheet with this name
Set wsEntry = .Sheets(entryName)
On Error GoTo 0 'stop ignoring errors
If wsEntry Is Nothing Then
wsTemp.Copy After:=.Sheets(.Sheets.Count)
Set wsEntry = .Sheets(.Sheets.Count) 'get the copy
wsEntry.Name = CStr(Nm.Text)
End If
With wsEntry
'transfer/update values from Master sheet
.Range("B2").Value = entryName
.Range("B3").Value = Nm.Offset(0,1)
'...etc
wsMaster.Hyperlinks.Add Anchor:=Nm,Address:="",_
SubAddress:=wsEntry.Range("A1").Address(,True),_
TextToDisplay:=Nm.Text
End With
Next Nm
wsMaster.Activate
If Not wasVisible Then wsTemp.Visible = xlSheetHidden
Application.ScreenUpdating = True
End With
MsgBox "All sheets created"
End Sub
),它适用于所有类型并且是比大锤子更安全的替代方案align_to
:
mem::transmute
对于 fn ref_all(x: &mut [u8; 2]) -> &mut u16 {
let (prefix,chunks,suffix) = unsafe {x.align_to_mut::<u16>()};
// you don't need these asserts but know that chunks might not always have an element
assert!(prefix.is_empty());
assert!(suffix.is_empty());
assert_eq!(chunks.len(),1);
&mut chunks[0]
}
来说,这应该没问题,尽管由于数字的字节顺序,它可能会导致依赖于体系结构的行为。对于其他类型,这样做会非常冒险。