risposta

16

Bene, se fossero in prima linea, come rileveresti quando hanno smesso di essere rifornito? L'unico modo sarebbe se il tipo di variabile fosse diverso dopo i parametri opzionali. Un po 'un requisito strano, quindi ha senso che tu li imponga solo per essere l'ultimo (salva il problema delle complesse regole per il rilevamento del parametro opzionale "finale").

Inoltre, è il modo più naturale per farlo quando si chiama la funzione.

+0

Sì sembra così ovvio ora :). Grazie. – Incognito

+0

@Incognito: funziona perfettamente in Ruby. Se ci sono parametri obbligatori dopo quelli opzionali, gli argomenti obbligatori vengono presi dalla fine dell'elenco degli argomenti. Tutto ciò che rimane sono gli argomenti opzionali. Vedi http://StackOverflow.Com/questions/2896106/why-optional-parameters-must-appear-at-the-end-of-the-declaration/2900474/#2900474 per un esempio. –

0

Solo supposizioni in natura: Forse ha qualcosa a che fare con le convenzioni di chiamata (ad esempio i parametri vengono premuti nello stack da sinistra a destra, i parametri opzionali vengono semplicemente omessi nel caso in cui non siano stati specificati).

+1

Ne dubito, penso che il chiamante invierà semplicemente i valori predefiniti. – tstenner

-1

Java e C# non hanno chiamato i parametri in modo da non si può fare:

myfunction(param1='Meh', optionalParam=2) 

quello che dovete fare:

myfunction('Meh', 2) 

Altrimenti

myFunction(2, 'Meh') 

è ambigua. Come si suppone che il compilatore sappia che intendevi inserire 2 nel set di parametri opzionale?

+7

C# 4.0 ha parametri con nome. – Incognito

0

I parametri facoltativi alla fine consentono di interrompere la specifica dei parametri ad un certo punto, ad es.

void Test(int a, optional int b = 0, optional int c = 0) { ... } 

Test(3); 

Se si effettua c un parametro obbligatorio, dovreste usare sintassi simile a questo:

Test(3, , 2); 
Test(a := 3, c := 2); 

Il vantaggio di un parametro opzionale è che può essere trattato come se wasn' t c'è. Se i parametri facoltativi si trovano nel mezzo dell'elenco dei parametri, ciò non è possibile senza "contare le virgole" o utilizzando una sintassi troppo dettagliata.

+1

Funziona perfettamente in Ruby. I parametri obbligatori all'inizio della lista dei parametri sono vincolati da sinistra a destra dall'inizio della lista degli argomenti. I parametri obbligatori alla fine dell'elenco dei parametri sono vincolati da destra a sinistra dalla fine dell'elenco degli argomenti. I parametri facoltativi sono associati da sinistra a destra dall'inizio dell'elenco di argomenti rimanente. Tutti gli argomenti rimasti sono destinati a riposare argomenti. Non fornire un argomento obbligatorio o fornire più di 'num_mandatory + num_optional' argomenti quando non ci sono parametri di riposo è un errore. –

2

consideri una dichiarazione del tipo:

int foo(float a, int b=0, int c=0, float d); 

(noto come ho definito i parametri defult nel mezzo della lista), che viene successivamente chiamato come

foo(0.0,1,2.0) 

Qual è la chiamata? In particolare è stato omesso b o c?

compilatore designer possono aggirare questo ostacolo utilizzando parametri denominati

foo(a=0,c=0,d=2.0) 

una funzionalità disponibile in pitone per esempio.

+1

Questa funzione è disponibile anche in C#: foo (a: 0, c: 0, d: 2.0). Il problema è cosa fare quando vengono fatte chiamate di posizione. – configurator

+2

Funziona bene in Ruby. I parametri obbligatori all'inizio della lista dei parametri sono vincolati da sinistra a destra dall'inizio della lista degli argomenti. I parametri obbligatori alla fine dell'elenco dei parametri sono vincolati da destra a sinistra dalla fine dell'elenco degli argomenti. I parametri facoltativi sono associati da sinistra a destra dall'inizio dell'elenco di argomenti rimanente. Tutti gli argomenti rimasti sono destinati a riposare argomenti. Non fornire un argomento obbligatorio o fornire più di 'num_mandatory + num_optional' argomenti quando non ci sono parametri di riposo è un errore. –

+0

Nel tuo specifico esempio, 'a' sarebbe legato a' 0.0', 'd' a' 2.0', 'b' a' 1' e 'c' otterrebbe il suo valore predefinito di' 0'. –

5

Questa è solo una regola arbitraria creata dai progettisti di quelle lingue specifiche.Non c'è assolutamente alcuna ragione tecnica per cui questa restrizione dovrebbe esserci.

funziona bene in rubino:

def foo(m1, m2, o1='o1', o2='o2', *rest, m3, m4) 
    return m1, m2, o1, o2, rest, m3, m4 
end 

foo(1, 2, 3, 4) 
# => [1, 2, 'o1', 'o2', [], 3, 4] 

foo(1, 2, 3, 4, 5) 
# => [1, 2, 3, 'o2', [], 4, 5] 

foo(1, 2, 3, 4, 5, 6) 
# => [1, 2, 3, 4, [], 5, 6] 

foo(1, 2, 3, 4, 5, 6, 7) 
# => [1, 2, 3, 4, [5], 6, 7] 

foo(1, 2, 3, 4, 5, 6, 7, 8) 
# => [1, 2, 3, 4, [5, 6], 7, 8] 

Tutti argomenti obbligatori devono essere forniti:

foo(1, 2, 3) 
# => ArgumentError: wrong number of arguments (3 for 4) 

Senza il parametro resto, fornendo più di argomenti number_of_optional number_of_mandatory + è un errore:

def bar(m1, m2, o1='o1', o2='o2', m3, m4) 
    return m1, m2, o1, o2, m3, m4 
end 

bar(1, 2, 3, 4, 5, 6, 7) 
# => ArgumentError: wrong number of arguments (7 for 6) 

Parametri obbligatori all'inizio del parametro l'elenco di ter è vincolato da sinistra a destra dall'inizio della lista degli argomenti. I parametri obbligatori alla fine dell'elenco dei parametri sono vincolati da destra a sinistra dalla fine dell'elenco degli argomenti. I parametri facoltativi sono associati da sinistra a destra dall'inizio dell'elenco di argomenti rimanente. Tutti gli argomenti rimasti sono destinati a riposare argomenti.

+0

Ovviamente corretto --- tanto più che hai un esempio funzionante da mostrare. Ma io cavillerò nella misura in cui i linguaggi c-like sono per lo più costituiti da semplici regole, e il modo rubino è prolisso: sarebbe una grande sorpresa in c, e almeno una piccola in C++. – dmckee

+0

@dmckee: L'unico linguaggio C-like che conosca argomenti facoltativi sarebbe C#, ma le sue regole sono enormemente complicate a causa di complesse interazioni tra argomenti opzionali e sovraccarico basato sull'arità. Trovo entrambi * almeno * allo stesso modo complicato, forse C# anche un po 'di più. –

Problemi correlati