2014-07-01 13 views
5

Piszę szybką funkcję is_prime w rdzę, i byłem pod wrażeniem, po prostu pisanie true było odpowiednikiem return true;. Ale to nie jest przypadek w mojej funkcji:Dlaczego usunięcie usunięcia daje mi błąd: oczekiwano "()", ale znalazłem

fn is_prime(number: i64) -> bool { 
    for i in range(2i64, number) { 
     if number % i == 0 && i != number { 
      false 
     } 
    } 
    true 
} 

to jednak da mi błąd:

"Error mismatched types: expected `()` but found `bool` (expected() but found bool) 

zastępując true i false z return true;/return false; działa, ale dlaczego przy użyciu poprzedniego nie skompilować ?

+0

BTW, i = 'check number' jest bezcelowe, ponieważ' range' nie obejmuje drugi punkt końcowy (czyli działa jak Python). Funkcję można również zapisać jako 'fn is_prime (number: i64) -> bool {! Range (2, number) .any (| i | number% i == 0)}'. – huon

+0

@dbaupp: Zamiast tego napisałem 'fn is_prime (number: i64) -> bool {range (2, number) .all (| i | number% i! = 0)}'. –

+0

@ChrisMorgan mówisz "all not", mówię "nie ma", de morgan mówi "kogo to obchodzi": P (Również dziwne, że mój oryginalny kod nie jest sformatowany w kodzie: 'fn is_prime (number: i64) -> bool {! range (2, number) .any (| i | number% i == 0)} '.) – huon

Odpowiedz

8

Rdza jest zorientowana na ekspresję. W dowolnym bloku ostatnie wyrażenie w środku jest wartością bloku. Tak więc dla funkcji ostatnia wartość w bloku jest traktowana jako wartość zwracana.

W innych blokach jednak tak nie jest - ostatnia wartość jest mimo wszystko traktowana jako wartość bloku, a nie jako wartość zwracana dla funkcji.

Take fragment w izolacji z tylko trochę dodana dla jasności:

let has_factor = if number % i == 0 && i != number { 
    false 
} 

Oznacza to, że wynik z rachunku if jako całość jest false jeśli klauzula jest prawdą, a ta wartość jest następnie należycie wstawiony do zmiennej has_factor. Jeśli klauzula jest nie prawdziwa, wówczas zostanie oceniona klauzula else. Biorąc pod uwagę, że nie ma innej klauzuli, jest tak, jakby napisano else { }, co jest równoważne z else {() }. Ten inny blok ma wartość (), typ jednostki. Teraz mamy niedopasowanie: jest blok if (a więc zmienna has_factor) typu bool, jak wymaga blok if, lub (), ponieważ blok [brak] else wymaga? Tutaj pojawia się błąd.

Podsumowanie: nie można po prostu pominąć słowa kluczowego return, ponieważ nie jest to określenie orientacji wyrażenia. Pod koniec funkcji ,, sprowadzają się do tej samej rzeczy, a forma sans-return powinna być preferowana, ale w innych lokalizacjach nie są one równoważne i return muszą być wyraźne.

kod końcowy:

fn is_prime(number: i64) -> bool { 
    for i in range(2, number) { 
     if number % i == 0 && i != number { 
      return false; 
     } 
    } 
    true 
} 
+0

Należy również zauważyć, że wartość wyrażenia for/while/loop jest zawsze '()'. –

Powiązane problemy