2015-04-13 3 views
1

Так как я понимаю, параметр char может быть либо None, либо любым символом, таким как 'a'.Как сравнить параметр char с char

Как сравнить параметр char с обычным символом.

let first = Some 'a';; 
let second = 'a';; 
let third= 'b';; 

Как сравнить первый и второй так, чтобы он возвращал true и first и third, чтобы он возвращал false.

ответ

4

В этом случае, вы можете сделать один из трех вещей, в зависимости от того, как вы используете

let first = Some 'a' 
let second = 'a' 
let third = 'b' 

Во-первых, вы можете превратить не-Option переменные в опции, а затем проверить (структурное) равенство на do:

if first = Some second then begin 
    Printf.printf "First and Second are equal!" 
end 

Во-вторых, вы можете использовать заявление соответствия. Это более стандартный способ «разворачивать» один вариант:

match first with 
| Some c -> 
    if c = second then print_endline "First and second are equal"; 
    if c = third then print_endline "First and third are equal." 
| None -> print_endline "None." 

Кроме того, вы можете обернуть матч в функции, как @ivg сделал в своем примере.

Наконец, вы можете использовать BatOption.get:

try 
    if BatOption.get first = second then print_endline "First and second are equal"; 
    if BatOption.get first = third then print_endline "First and third are equal"; 
with 
    No_value -> print_endline "ERROR: No value!!" 

Если вы используете BatOption.get, вы хотите, чтобы обернуть его в try/with, потому что если first является None, это поднимет No_value исключение.

В общем, однако, match - это самый стандартный способ его выполнения. Как отмечал @ivg, использование совпадения немного быстрее, чем создание объекта Option и выполнение сравнения (особенно при ограничении типа и генерации функции). Если скорость не вызывает большого беспокойства, то все будет хорошо. Это зависит от вас и того, что кажется наиболее читаемым.

Кроме того, как неродственное сторона примечания/предложение: не используйте двойную точку с запятой, кроме как после main, например,

let main() = begin 
... 
end ;; 
main() ;; 

Вы только когда-либо нужны эти две двойных точек с запятой. Эта практика позволяет забыть все странные правила с двойной точкой с запятой и обеспечить, чтобы ваши программы «просто работали».

+1

Отличный ответ. Спасибо. – rightDrop

+4

Ваше второе решение неверно: при сопоставлении шаблонов 'second' используется в позиции шаблона как переменной catch-all, так что эта ветка всегда будет использоваться. Я думаю, вы бы хотели написать что-то вроде 'match first with Some c -> if c = second then ... else if c = third then ... else ... | None -> ... ' – Virgile

+0

А, хорошо поймайте! Ред. –

2

Я бы порекомендовал вам использовать наиболее четкое решение:

first = Some second 

хотя, можно сказать, что это не очень эффективный способ, так как он выполняет дополнительное выделение. Но вы не должны беспокоиться об этом, если только он не используется в очень плотной петле. Если это плотный цикл, и вы действительно точно определили с трассирующими, что вам нужно, чтобы оптимизировать его, то вы можете использовать

let option_contains opt (x : char) = match opt with 
    | None -> false 
    | Some y -> x = y 

Примечание, эта функция особенно ограничение принимать только значения типа char, что делает это очень быстро. Но опять же, это просто игра в оптимизации. В общем, просто придерживайтесь наиболее читаемого решения, то есть first = Some second.

+3

Майкл, вы совершенно смущены, ваш пример с несвязанным «y» - полная глупость, лучше удалить его. – ivg

+0

ivg, мой ошибка, спасибо, что указал. Я смутил себя этим примером. Я обновил свой ответ, удалив второе редактирование и удалив мою рекомендацию, чтобы избежать «first = Some second». –

Смежные вопросы