De termen impliciet en expliciet nemen enige wennen wanneer u ze voor het eerst hoort. Als je ze hoort in termen van programmeren wat betekent dat precies voor jou? Is de ene manier beter dan de andere? Hier zullen we gaan over elk van deze ideeën en geven voorbeelden met een aantal ontwerp patroon voordelen die kunnen komen van hen.
de termen
in programmeren wordt impliciet vaak gebruikt om te verwijzen naar iets dat achter de schermen voor je wordt gedaan door andere code., Expliciet is de handmatige aanpak om de wijziging te realiseren die u wilt hebben door het schrijven van de instructies die expliciet moeten worden gedaan. In het kleinere plaatje, impliciet en expliciet zijn vaak termen gebruikt voor het gieten van types in het type dat je zou hebben het te zijn. In het grotere plaatje heb je het misschien over Conventie over configuratie waar conventie is wat impliciet voor je wordt gedaan door een code base of framework en configuratie gewoon expliciete instellingen zijn.,
Er zijn ook verschillen in geschiktheid of voordeel voor elk gebruik afhankelijk van de programmeertaal in kwestie en of de taal statisch of dynamisch wordt getypt. Het hangt er ook van af of dingen kunnen worden afgeleid uit een run time of tijdens het compileren. Om deze redenen kan een bewering dat de ene methodologie beter is dan de andere alleen maar waar zijn binnen een enge context, omdat je rekening moet houden met het ontwerp voor programmeertalen en programma ‘ s in kwestie.,
een voorbeeld van impliciete en expliciete type casting in C is als volgt:
int implicit;implicit = 4.5;int explicit;explicit = (int)4.5;
Hier zijn de variabelnamen implicit
en explicit
gedefinieerd als van het type int
. Eenmaal gegeven een waarde 4.5
de impliciete versie laat de compiler converteren wat normaal een float of double type zou zijn naar een geheel getal terwijl de expliciete versie het expliciet naar een geheel getal heeft gegoten met het gebruik van (int)
zijnde wat het type Cast.,
statisch getypte talen
in statisch getypte talen zoals Rust zal een overgrote meerderheid van waardecreatie en toewijzing expliciete type annotatie vereisten hebben, met een uitzondering voor waar de compiler het type kan afleiden. Het volgende is een voorbeeld dat expliciete en impliciete types in Rust laat zien.
fn add_one(input: u8) -> u8 { input + 1}let four = add_one(3);
Hier is de methode add_one
expliciet over het invoer-en uitvoertype., Het nummer 1
dat hier wordt toegevoegd, wordt impliciet een u8
nummer gemaakt tijdens het compileren, omdat de context helpt het type en de toevoeging voor u8
is alleen geïmplementeerd om te werken met u8
nummers. De laatste regel wordt impliciet getypt als een u8
omdat de methode zelf het type definieert dat zal worden geretourneerd.
wat kan worden afgeleid in Rust is vrij indrukwekkend met het gebruik van generieke geneesmiddelen. Maar het gebruik van gevolgtrekking is beperkt tot dingen die bekend zijn tijdens het compileren., Als het niet bekend is tijdens het compileren, moet je het type expliciet definiëren op elk punt van toewijzing. Neem de volgende methodedefinitie:
use std::ops::Add;fn add_both<T: Add>(a: T, b: T) -> T::Output { a + b}
hier T
kan elk type zijn dat de eigenschap implementeert Add
. Het T::Output
type wordt gedefinieerd als de Add eigenschap is gedefinieerd voor uw specifieke type en is over het algemeen hetzelfde type als T
zelf in dit geval. Als we nu twee getallen als parameters geven zal de compiler het type afleiden.,
let x = add_both(3 , 4 ); // implicit typelet y: u8 = add_both(3u8 , 4u8 ); // explicit typelet z: u32 = add_both(3u32, 4u32); // explicit type
wanneer ik de bovenstaande code uitvoer wordt x
afgeleid als het type i32
. De voorbeelden y
en z
vereisen dat de invoerparametertypes bekend zijn als de gevolgtrekking voor T::Output
is niet noodzakelijk hetzelfde als wat T kan worden afgeleid als. Het zou standaard i32
en dan een i32
toewijzen als een u8
of u32
is gewoon verkeerd.,
dynamisch getypte talen
nu met dynamisch getypte talen, moet u zich minder zorgen maken over typen, per se, en meer over impliciete of expliciete objecten of gedrag. Modellering code rond objecten die hetzelfde gedrag hebben is wat bekend staat als duck Typen dat is een hoger domein van denken in object-georiënteerde programmering waar het omgaan met die objecten is impliciet. Terwijl het modelleren van de code rond specifieke object klassen is net als het gebruik van expliciete of impliciete typen., Maar als je een object accepteert als invoer, dan moet de code in die sectie ofwel verschillende objecten expliciet behandelen of die verantwoordelijkheid elders overdragen.
ter verduidelijking, wanneer je code schrijft om verschillende soorten dingen af te handelen, dan schrijf je expliciete code. Maar als dezelfde code al geschreven is en je hergebruikt het met een eenvoudige methode aanroep, dan is het gedrag in deze nieuwe context dan impliciet. Impliciet zijn dingen gedaan alsof automatisch en behandeld buiten uw huidige scope.,
in Ruby hebben de meeste types een ontwerp voor expliciete of impliciete conversie. Het idee is dat de impliciete conversiemethoden bedoeld zijn om te worden gebruikt in impliciete contexten en de expliciete conversies zijn bedoeld voor ontwikkelaars om inline te schrijven in veel meer contexten. Ik wil dit als voorbeeld stellen.
# explicit"4".to_i + "5".to_i# => 9# implicitclass Seven def to_int 7 endendArray.new(Seven.new)# =>
Hier maakt het expliciete voorbeeld het voor de lezer heel duidelijk dat we String
objecten converteren naar een Integer
object en optellen tussen de twee., En het impliciete voorbeeld is niet zo duidelijk voor de lezer als de Array.new
methode impliciet De to_int methode aanroept op welke parameter het ook is gegeven. De Integer klasse heeft de methode to_int gedefinieerd op elke instantie ervan die gewoon zelf retourneert. Als u 42.to_int
schrijft, krijgt u gewoon 42
terug. Dit gebruik van het gebruik van impliciete conversie als input guard Voor methode oproepen is een geweldig ontwerp voor type veiligheid door ontwerp. Hier is wat er gebeurt als je het de verkeerde soort object als invoer geeft die to_int
niet definieert.,
Array.new("32")# TypeError (no implicit conversion of String into Integer)
het mislukt niet alleen, het geeft ons een nuttig bericht dat een impliciete conversie werd geprobeerd en vertelt de klasse van object gegeven en de klasse van object verwacht. Impliciete conversiemethoden in Ruby is een manier om te zeggen dat dit object echt is wat je verwacht. En expliciete conversie is gewoon het maken van de conversie naar het type verwacht.
Ruby heeft impliciete en expliciete opties voor veel van zijn kernobjecten.,
Ruby heeft ook een paar klassen met klassemethoden die ofwel een impliciete conversie uitvoeren of nihil retourneren en die methodenaam is try_convert
.
We kunnen Ruby ’s voorbeeld volgen met Array.new
en hebben een goede bescherming voor het soort invoerparameters dat we krijgen door impliciete conversies te ontwerpen voor onze eigen aangepaste types. In dit voorbeeld, omdat to_f
een expliciete conversie is naar een Float nummer in Ruby, gebruiken we as_
als een voorvoegsel in plaats van to_
., Hier is een basisvoorbeeld van betrokkenheid als een patroon voor veiligheid.
Dit zal andere ontwikkelaars helpen die de Bar
Klasse gebruiken om het niet door te geven als een incompatibele parameter. Het volgt een conventie binnen de Ruby taal en moet veel gemakkelijker voor ontwikkelaars te begrijpen met meer behulpzame fouten. Als u andere objecten hebt die u wilt converteren naar een Foo-object, dan kunt u een as_f
methode definiëren voor een expliciete conversie en de ontwikkelaar die dat nieuwe object gebruikt zal expliciet zijn in het gebruik Bar.new(Baz.new.as_f)
., Dit zorgt ervoor dat de code zo goed werkt als Bar
en Foo
al werken.
samenvatting
de handeling van impliciete en expliciete codering, en impliciete en expliciete code, wordt gedefinieerd door context van uitvoering van aanvullend gedrag of type instelling/casting. Impliciete of expliciete methoden worden specifiek gedefinieerd door de context waarin ze bedoeld zijn om te worden gebruikt. Impliciete code kan een zeer mooie ervaring zijn als dingen goed worden genoemd omdat het de dingen eenvoudig houdt.,
echter, impliciete code, code die dingen achter de schermen voor je doet, kan ook een moeilijk probleem zijn om op te lossen als het verkeerd wordt gedaan. Expliciete code maakt de code duidelijk als je er naar kijkt omdat de details van wat er gedaan wordt al voor je liggen en je niet elders problemen hoeft op te sporen, maar over het algemeen betekent het veel meer werk om het te schrijven. Op zichzelf kan het overweldigend worden, dus het vinden van een goede balans tussen de twee is vaak de beste oplossing. Wees expliciet wanneer je moet, en impliciet wanneer het ontwerp en de naamgeving concepten zijn gemakkelijk te begrijpen., Het zal zorgen voor een handigere ontwikkelingservaring.