Какая разница между "let() =" и "let _ =";

let () = Random.self_init();;
let _ = Random.self_init ();;
│- : unit = ()

Кажется, что "let()" ничего не возвращает?

С уважением!

Ответ 1

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 _ = немного короче (я видел этот аргумент). (Обратите внимание, что с редактором, который автоматически закрывает круглые скобки, количество нажатий клавиш одинаковое; -)

Ответ 2

Я не эксперт 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 = ()