let () = Random.self_init();;
let _ = Random.self_init ();;
│- : unit = ()
Кажется, что "let()" ничего не возвращает?
С уважением!
let () = Random.self_init();;
let _ = Random.self_init ();;
│- : unit = ()
Кажется, что "let()" ничего не возвращает?
С уважением!
let
- это ключевое слово, используемое для определения новых переменных, например, в следующей конструкции:
let pattern = expr
Например
let a = 2
присваивает значение 2
имени a
. (Обратите внимание, что это не способ присвоить значение уже существующей переменной, но это еще одна тема).
Но шаблон слева от знака =
может быть больше, чем просто имя. Например,
let (a,b) = (42,"foo")
определяет как a
, так и b
, соответственно 42
и "foo"
.
Конечно, типы с обеих сторон должны совпадать.
Что здесь имеет место: обе стороны имеют тип int * string
.
Выражения справа от знака =
также могут быть разработаны, например
let foo =
let temp = String.make 10 'a' in
temp.[2] <- 'b';
temp
определяет foo
как строку "aabaaaaaaa"
. (В качестве дополнительной заметки это также гарантирует, что temp
является локальным для этого фрагмента кода).
Теперь позвольте использовать оба: слева, соответствующие шаблону значения типа unit
, а справа - выражение типа unit
:
let () = Printf.printf "Hello world!\n"
Это объясняет конструкцию let () =
.
Теперь, о let _
, просто нужно знать, что _
может использоваться в шаблоне как подстановочный знак: он соответствует значениям любого типа и не связывает какое-либо имя. Например,
let (a,_) = (42,"foo")
определяет a
как 42
и отбрасывает значение "foo"
. _
означает "Я знаю, что есть что-то здесь, и я прямо говорю, что не буду использовать его, поэтому я его не называю". Здесь _
использовался для сопоставления значений типа string
, но он может соответствовать значению любого типа, например int * string
:
let _ = (42,"foo")
который не определяет какую-либо переменную и не очень полезен. Такие конструкции полезны, когда правая сторона имеет побочные эффекты, например:
let _ = Printf.printf "Hello world!\n"
который объясняет вторую часть вопроса.
Практические цели
Оба используются, и это скорее вопрос вкуса, следует ли использовать тот или иной.
let () =
немного безопаснее, поскольку он имеет проверку компилятора, что правая сторона имеет тип unit
.
Значение любого другого типа, кроме единицы, часто является ошибкой.
let _ =
немного короче (я видел этот аргумент). (Обратите внимание, что с редактором, который автоматически закрывает круглые скобки, количество нажатий клавиш одинаковое; -)
Я не эксперт OCaml, хотя позвольте мне поделиться чем-то:)
let
в OCaml может представлять две вещи:
Используя примеры, вы можете ясно видеть, как это работает: Назначение переменных:
# let ten = 10;;
val ten : int = 10
# let hello_world_string = "Hello World";;
val hello_world_string : string = "Hello World"
Объявление функций:
# let sum a b = a+b;;
val sum : int -> int -> int = <fun>
# sum 2 3;;
- : int = 5
Итак, отвечая на вопрос о различии между let() = и пусть _ = is:
В первом примере вы объявляете функцию, которая не имеет имени, параметров или инструкций, которые должны выводить устройство. Второй пример: вы не назначаете _, то есть шаблон OCaml, любое значение.
Как мы увидим ниже, мы можем определить функцию, которая будет выполняться немедленно, потому что мы больше не сможем ее вызывать:
# let () = print_string "Hello";;
Hello
Или назначьте подстановочный знак OCaml тип и значение или функцию:
# let _ = 10;;
- : int = 10
# let _ = print_string "Maybe I answered your question :) ";;
Maybe I answered your question :) - : unit = ()