I termini impliciti ed espliciti richiedono un po ‘ di tempo per abituarsi quando li senti per la prima volta. Quando li senti in termini di programmazione cosa significa esattamente per te? È un modo migliore di un altro? Qui andremo oltre ciascuna di queste idee e fornire esempi con alcuni vantaggi modello di progettazione che possono venire da loro.
I termini
Nella programmazione, implicito è spesso usato per riferirsi a qualcosa che è fatto per te da altro codice dietro le quinte., Esplicito è l’approccio manuale per realizzare il cambiamento che si desidera avere scrivendo le istruzioni da fare esplicitamente. Nell’immagine più piccola, implicito ed esplicito sono spesso termini usati per lanciare i tipi nel tipo che vorresti fosse. Nel quadro più ampio, potresti parlare di convenzione sulla configurazione in cui la convenzione è ciò che viene implicitamente fatto per te da una base di codice o un framework e la configurazione è semplicemente impostazioni esplicite.,
Ci sono anche differenze di appropriatezza o beneficio per l’uso a seconda del linguaggio di programmazione in questione e se il linguaggio è tipizzato staticamente o dinamicamente tipizzato. Dipende anche se le cose possono essere dedotte da un tempo di esecuzione o durante la compilazione. A causa di questi fattori, affermare che una metodologia è migliore di un’altra può essere vera solo all’interno di contesti ristretti in quanto è necessario prendere in considerazione il design per i linguaggi di programmazione e i programmi in questione.,
Un esempio di tipo implicito ed esplicito casting in C è come indicato di seguito:
int implicit;implicit = 4.5;int explicit;explicit = (int)4.5;
Ecco i nomi delle variabili implicit
e explicit
sono stati definiti di tipo int
. Una volta dato un valore 4.5
la versione implicita ha il compilatore che converte quello che normalmente sarebbe un tipo float o double in un intero mentre la versione esplicita lo ha esplicitamente lanciato su un intero con l’uso di (int)
che è ciò che lancia il tipo.,
Linguaggi tipizzati staticamente
Nei linguaggi tipizzati staticamente come Rust, la maggior parte della creazione di valore e dell’assegnazione avrà requisiti di annotazione di tipo espliciti con un’eccezione per ovunque il compilatore possa dedurre il tipo. Di seguito è riportato un esempio che mostra i tipi espliciti e impliciti in Rust.
fn add_one(input: u8) -> u8 { input + 1}let four = add_one(3);
Qui il metodoadd_one
è esplicito sul tipo di input e tipo di output., Il numero 1
essere aggiunto qui è fatta implicitamente un u8
numero al momento della compilazione del contesto consente di dedurre il tipo e l’aggiunta di u8
è implementata solo per lavorare con u8
numeri. L’ultima riga viene implicitamente digitata per essere un u8
poiché il metodo stesso definisce il tipo che verrà restituito.
Ciò che si può dedurre in Rust è piuttosto impressionante con l’uso di generici. Ma l’uso dell’inferenza è limitato a cose che possono essere conosciute in fase di compilazione., Se non può essere conosciuto in fase di compilazione, è necessario definire esplicitamente il tipo in qualsiasi punto di assegnazione. Prendi la seguente definizione del metodo:
use std::ops::Add;fn add_both<T: Add>(a: T, b: T) -> T::Output { a + b}
Qui T
può essere qualsiasi tipo che implementa il tratto Add
. Il tipoT::Output
è definito quando il tratto di aggiunta è definito per il tuo tipo specifico ed è generalmente lo stesso tipo diT
in questo caso. Ora se forniamo due numeri come parametri il compilatore dedurrà il tipo ad esso.,
let x = add_both(3 , 4 ); // implicit typelet y: u8 = add_both(3u8 , 4u8 ); // explicit typelet z: u32 = add_both(3u32, 4u32); // explicit type
Quando eseguo il codice precedentex
si deduce che sia il tipoi32
. Gli esempiy
ez
richiedono che i tipi di parametri di input siano noti quando forniti alla funzione come inferenza perT::Output
non è necessariamente lo stesso di ciò che T può essere dedotto come. Sarebbe predefinito i32
e quindi assegnare un i32
come u8
o u32
è semplicemente sbagliato.,
Linguaggi tipizzati dinamicamente
Ora con i linguaggi tipizzati dinamicamente, devi preoccuparti meno dei tipi, di per sé, e più di oggetti o comportamenti impliciti o espliciti. Modellare il codice intorno agli oggetti che hanno lo stesso comportamento è ciò che è noto come duck typing che è un dominio più alto del pensiero nella programmazione orientata agli oggetti in cui la gestione di tali oggetti è implicita. Mentre modellare il codice attorno a classi di oggetti specifiche è molto simile all’uso della digitazione esplicita o implicita., Ma quando si accetta qualsiasi tipo di oggetto come input, il codice in quella sezione deve gestire esplicitamente oggetti diversi o consegnare tale responsabilità altrove.
Per chiarimenti, quando stai scrivendo codice per gestire diversi tipi di cose, allora stai scrivendo codice esplicito. Tuttavia, quando questo stesso codice è già stato scritto e lo si sta riutilizzando con una semplice chiamata al metodo, il comportamento in questo nuovo contesto è quindi implicito. Implicito essere cose fatte come se automaticamente e gestite al di fuori del tuo ambito attuale.,
In Ruby, la maggior parte dei tipi ha un design per la conversione esplicita o implicita. L’idea è che i metodi di conversione impliciti siano pensati per essere utilizzati in contesti impliciti e che le conversioni esplicite siano pensate per gli sviluppatori per scrivere in linea in molti più contesti. Permettetemi di dimostrarlo con l’esempio.
# explicit"4".to_i + "5".to_i# => 9# implicitclass Seven def to_int 7 endendArray.new(Seven.new)# =>
Qui l’esempio esplicito rende molto evidente al lettore che stiamo convertendo String
oggetti in un Integer
oggetto ed eseguendo l’aggiunta tra i due., E l’esempio implicito non è così ovvio per il lettore in quanto il metodo Array.new
chiama implicitamente il metodo to_int su qualsiasi parametro venga fornito. La classe Integer ha il metodo to_int definito su ogni istanza di esso che restituisce semplicemente self. Se si scrive 42.to_int
si ottiene semplicemente indietro 42
. Questo uso dell’uso della conversione implicita come protezione di input per le chiamate al metodo è un ottimo design per la sicurezza del tipo in base alla progettazione. Ecco cosa succede se gli dai il tipo di oggetto sbagliato come input che non definisce to_int
.,
Array.new("32")# TypeError (no implicit conversion of String into Integer)
Non solo fallisce, ma ci dà un messaggio utile che è stata tentata una conversione implicita e indica la classe di oggetto data e la classe di oggetto che si aspetta. I metodi di conversione impliciti in Ruby sono un modo per dire che questo oggetto è davvero quello che ti aspetti. E la conversione esplicita sta semplicemente facendo la conversione al tipo previsto.
Ruby ha opzioni implicite ed esplicite per molti dei suoi oggetti principali.,
Ruby ha anche alcune classi con metodi di classe che eseguiranno una conversione implicita o restituiranno nil e il nome del metodo ètry_convert
.
Possiamo seguire l’esempio di Ruby conArray.new
e avere una buona guardia per il tipo di parametri di input che ci vengono dati progettando conversioni implicite per i nostri tipi personalizzati. Per questo esempio, poiché to_f
è una conversione esplicita in un numero Float in Ruby, useremoas_
come prefisso invece dito_
., Ecco un esempio di base di implicitness come modello per la sicurezza.
Ora questo aiuterà gli altri sviluppatori che usano la classeBar
a non passarla come parametro incompatibile. Segue una convenzione all’interno del linguaggio Ruby e dovrebbe essere molto più facile da capire per gli sviluppatori con errori più utili. Quando hai altri oggetti che vorresti convertire in un oggetto Foo, puoi definire un metodo as_f
su di esso per una conversione esplicita e lo sviluppatore che usa quel nuovo oggetto sarà esplicito nel suo uso Bar.new(Baz.new.as_f)
., Ciò garantisce che il codice funzioni in modo tale che Bar
e Foo
stiano già funzionando.
Sommario
L’atto di codifica implicita ed esplicita, e il codice implicito ed esplicito, è definito dal contesto di esecuzione di comportamento aggiuntivo o impostazione del tipo / casting. In particolare, i metodi impliciti o espliciti sono definiti dai contesti in cui sono destinati ad essere utilizzati. Il codice implicito può essere un’esperienza molto bella se le cose sono ben denominate in quanto mantengono le cose semplici.,
Tuttavia, il codice implicito, il codice che fa le cose dietro le quinte per te, può anche essere un problema difficile da risolvere quando fatto male. Il codice esplicito rende il codice chiaro quando lo si guarda come le specifiche di ciò che viene fatto sono già disposte prima di te e non devi rintracciare i problemi altrove, ma in genere significa molto più lavoro per scriverlo. Da solo può diventare schiacciante in modo da trovare un giusto equilibrio tra i due è spesso la soluzione migliore. Sii esplicito quando devi e implicito quando i concetti di progettazione e denominazione sono facili da capire., Farà per un’esperienza di sviluppo più conveniente.