1116 Да, это безопасно. Я написал бы это как:
use std::ptr;
fn safe_wrapper(opt: Option<&u8>) {
let p = opt.map_or_else(ptr::null, |x| x);
unsafe { ffi_call(p) }
}
Если вы обнаружите, что пишете это много, вы можете превратить это в черту и сократить до одного вызова метода.
указатель может быть признан недействительным при прохождении через замыкание
blockquote>Это может быть , если вы каким-либо образом лишите его законной силы. Поскольку функция берет ссылку, вы точно знаете, что упомянутое значение будет действовать в течение всего времени вызова функции - вот цель проверки заемщика в Rust.
Единственный способ для указателя стать недействительным - это изменить значение указателя (например, добавить к нему смещение). Так как ты этого не делаешь, это нормально.
Гарантирует ли Rust, что окончательный указатель будет указывать на то же, что и исходная ссылка?
blockquote>Это зависит от того, что вы подразумеваете под «финалом». Преобразование ссылки на указатель всегда приведет к тому, что оба значения будут содержать одно и то же место в памяти. Все остальное было бы преднамеренно злонамеренным, и никто бы никогда не использовал Rust для начала.
Если
blockquote>T
равноCopy
, значит ли это изменить семантику значимым образом?Нет. Кроме того, мы говорим о
&T
, который всегда всегдаCopy
См. Также:
- Параметр преобразования < & amp; mut T & gt ; to * mut T
- Должны ли мы использовать Option или ptr :: null для представления нулевого указателя в Rust?
- Допустимо ли использовать ptr :: NonNull в FFI?
интерфейс FFI, который я использую, имеет семантику заимствования (я выделяю что-то и передаю указатель на него ]), а не семантика владения
blockquote>Чтобы было ясно, вы не можете определить владение, основываясь исключительно на типах функций.
Эта функция C становится владельцем:
void string_free(char *)
Эта функция C заимствует:
size_t string_len(char *)
Оба получают указатель. Rust улучшает эту ситуацию, четко разграничивая, что такое заем и передача права собственности.
blockquote>extern "C" { // Parameter may be null fn ffi_call(*const T); }
Этот код не имеет смысла; он не определяет универсальный тип
T
, и функции FFI в любом случае не могут иметь универсальные типы.
Вот некоторые инструкции, как Вы можете свой сценарий, чтобы быть более удобными в сопровождении.
Conver исходный сценарий как фильтр.
filter HasChanged {
param($file)
# if $file's MD5 has does not exist
# then return $_
}
Затем просто отфильтруйте все файлы, которые обновляются и копируют их.
# Note that "Copy-Item" here does not preserve original directory structure
# Every updated file gets copied right under "C:\MyTest2"
ls C:\MyTest -Recurse | HasChanged | Copy-Item -Path {$_} C:\MyTest2
Или можно создать другую функцию, которая генерирует подкаталог
ls C:\MyTest -Recurse | HasChanged | % { Copy-Item $_ GenerateSubDirectory(...) }
Я нашел решение..., но не уверенным, что это лучше всего из перспективы производительности:
$Source = "c:\scripts"
$Destination = "c:\test"
###################################################
###################################################
Param($Source,$Destination)
function Get-FileMD5 {
Param([string]$file)
$mode = [System.IO.FileMode]("open")
$access = [System.IO.FileAccess]("Read")
$md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
$fs = New-Object System.IO.FileStream($file,$mode,$access)
$Hash = $md5.ComputeHash($fs)
$fs.Close()
[string]$Hash = $Hash
Return $Hash
}
function Copy-LatestFile{
Param($File1,$File2,[switch]$whatif)
$File1Date = get-Item $File1 | foreach-Object{$_.LastWriteTimeUTC}
$File2Date = get-Item $File2 | foreach-Object{$_.LastWriteTimeUTC}
if($File1Date -gt $File2Date)
{
Write-Host "$File1 is Newer... Copying..."
if($whatif){Copy-Item -path $File1 -dest $File2 -force -whatif}
else{Copy-Item -path $File1 -dest $File2 -force}
}
else
{
#Don't want to copy this in my case..but good to know
#Write-Host "$File2 is Newer... Copying..."
#if($whatif){Copy-Item -path $File2 -dest $File1 -force -whatif}
#else{Copy-Item -path $File2 -dest $File1 -force}
}
Write-Host
}
# Getting Files/Folders from Source and Destination
$SrcEntries = Get-ChildItem $Source -Recurse
$DesEntries = Get-ChildItem $Destination -Recurse
# Parsing the folders and Files from Collections
$Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer}
$SrcFiles = $SrcEntries | Where-Object{!$_.PSIsContainer}
$Desfolders = $DesEntries | Where-Object{$_.PSIsContainer}
$DesFiles = $DesEntries | Where-Object{!$_.PSIsContainer}
# Checking for Folders that are in Source, but not in Destination
foreach($folder in $Srcfolders)
{
$SrcFolderPath = $source -replace "\\","\\" -replace "\:","\:"
$DesFolder = $folder.Fullname -replace $SrcFolderPath,$Destination
if(!(test-path $DesFolder))
{
Write-Host "Folder $DesFolder Missing. Creating it!"
new-Item $DesFolder -type Directory | out-Null
}
}
# Checking for Folders that are in Destinatino, but not in Source
foreach($folder in $Desfolders)
{
$DesFilePath = $Destination -replace "\\","\\" -replace "\:","\:"
$SrcFolder = $folder.Fullname -replace $DesFilePath,$Source
if(!(test-path $SrcFolder))
{
Write-Host "Folder $SrcFolder Missing. Creating it!"
new-Item $SrcFolder -type Directory | out-Null
}
}
# Checking for Files that are in the Source, but not in Destination
foreach($entry in $SrcFiles)
{
$SrcFullname = $entry.fullname
$SrcName = $entry.Name
$SrcFilePath = $Source -replace "\\","\\" -replace "\:","\:"
$DesFile = $SrcFullname -replace $SrcFilePath,$Destination
if(test-Path $Desfile)
{
$SrcMD5 = Get-FileMD5 $SrcFullname
$DesMD5 = Get-FileMD5 $DesFile
If(Compare-Object $srcMD5 $desMD5)
{
Write-Host "The Files MD5's are Different... Checking Write
Dates"
Write-Host $SrcMD5
Write-Host $DesMD5
Copy-LatestFile $SrcFullname $DesFile
}
}
else
{
Write-Host "$Desfile Missing... Copying from $SrcFullname"
copy-Item -path $SrcFullName -dest $DesFile -force
}
}
# Checking for Files that are in the Destinatino, but not in Source
foreach($entry in $DesFiles)
{
$DesFullname = $entry.fullname
$DesName = $entry.Name
$DesFilePath = $Destination -replace "\\","\\" -replace "\:","\:"
$SrcFile = $DesFullname -replace $DesFilePath,$Source
if(!(test-Path $SrcFile))
{
Write-Host "$SrcFile Missing... Copying from $DesFullname"
copy-Item -path $DesFullname -dest $SrcFile -force
}
}