Borrow en AsRef stellen beide referentie-naar-referentie conversie mogelijk, maar Borrow legt strikte contractuele garanties op aan gelijkheid en hashing semantiek. Wanneer een type Borrow<T> implementeert, belooft het dat borrow() een waarde retourneert die gelijk vergeleken wordt (via Eq) en identieke hashwaarden (via Hash) produceert in vergelijking met het oorspronkelijke type. AsRef mist deze beperkingen; het staat slechts goedkope conversie toe zonder te eisen dat de geconverteerde weergave hetzelfde hash- of gelijkheidsgedrag behoudt. HashMap vereist Borrow voor zijn get-methode omdat het moet waarborgen dat een als String ingevoegde sleutel betrouwbaar kan worden opgehaald met behulp van een &str, wat garandeert dat beide types naar dezelfde interne emmer verwijzen en tijdens botsingsresolutie gelijk worden vergeleken.
Je ontwerpt een hoogpresterende routeringstabel voor een HTTP-proxy waar route-sleutels zijn opgeslagen als eigendom String objecten, maar inkomende verzoeken bieden padsegmenten als &str-snedes die zijn geparsed uit de netwerkkbuffer.
Je evalueert drie implementatiestrategieën. Ten eerste zou je alle sleutels kunnen normaliseren naar String tijdens de lookup, wat type uniformiteit garandeert; dit blijkt echter onbetaalbaar vanwege allocaties bij elk verzoek. Ten tweede overweeg je AsRef<str> te gebruiken als de lookup-grens, zodat zowel String als &str kunnen worden geconverteerd naar &str; echter, AsRef staat implementaties toe waarbij de gerefereerde gegevens verschillende Unicode-normalisatievormen of coderingen kunnen gebruiken, waardoor "café" als String en "café" als &str naar verschillende emmers hash-en en cache-misses opleveren ondanks logische gelijkheid. Ten derde neem je Borrow<str> aan, wat contractueel garandeert dat String::borrow() en &str identieke Hash en Eq resultaten produceren, wat zorgt voor consistente emmerindexering.
Je kiest voor de Borrow-benadering omdat het per-verzoekallocaties elimineert terwijl het de hashconsistentie behoudt die nodig is voor correcte route-resolutie. Het resultaat is een zero-copy lookup-mechanisme dat &str van het netwerk accepteert en correct overeenkomt met vooraf ingevoegde String-routes zonder semantische afwijking.
Waarom leidt het gebruik van AsRef<str> in plaats van Borrow<str> voor HashMap-lookup tot subtiele retrieval-fouten?
Hoewel AsRef<str> het mogelijk maakt om zowel String als &str naar &str om te zetten, biedt het geen garantie dat de hash van de geconverteerde referentie overeenkomt met de hash van de oorspronkelijke eigendomwaarde. HashMap gebruikt de hashwaarde om de opslagemmer te bepalen; als String en &str verschillende hashes produceerden voor dezelfde logische inhoud (bijvoorbeeld door verschillende interne representaties of normalisatie), zou de lookup de verkeerde emmer doorzoeken en None retourneren ondanks dat de sleutel bestaat. Borrow voorkomt dit door te vereisen dat hash(x.borrow()) == hash(x) en x.borrow() == x, wat ervoor zorgt dat heterogene types altijd naar identieke opslaglocaties worden mapped wanneer ze logisch gelijk zijn.
Waarom vereist HashMap zowel Borrow als Eq/Hash trait-bounds tegelijkertijd, gezien het feit dat Borrow al gelijkheidssemantiek impliceert?
Borrow stelt equivalentie vast tussen de eigendom- en geleende representaties, maar Eq en Hash definiëren de werkelijke vergelijking en hashing-algoritmes. Borrow garandeert alleen dat deze algoritmes consistente resultaten produceren over de typegrens; het implementeert ze niet. De HashMap heeft Eq nodig om botsingen binnen een emmer op te lossen en Hash om de emmerindex aanvankelijk te berekenen. Zonder Borrow zou de kaart geen &str veilig kunnen accepteren om een String-sleutel te vinden; zonder Eq en Hash zou het de nodige vergelijkingen of de hashwaarde helemaal niet kunnen berekenen.
Hoe verschilt Borrow van Deref bij het projecteren via slimme pointers en waarom vertrouwt HashMap op Borrow voor String-sleutels in plaats van Deref-coercie?
Deref biedt automatische coercie naar een doeltype en impliceert een referentierelatie, maar het vereist geen hash- of gelijkheidconsistentie tussen de slimme pointer en zijn doel. Een hypothetische slimme pointer zou Deref kunnen naar een gecached of getransformeerd beeld dat verschilt van de interne representatie die voor hashing wordt gebruikt. Borrow vereist expliciet dat de geleende weergave identieke Hash en Eq semantiek behoudt als het origineel. HashMap gebruikt Borrow voor String omdat het moet waarborgen dat "key" (als String) en "key" (als &str) in dezelfde emmer botsen; Deref-coercie alleen mist de formele garantie dat String::deref() en &str hetzelfde hash-implementatietraject delen, terwijl Borrow deze invariant formaliseert.