F # обработка значений и ссылок - PullRequest
2 голосов
/ 13 февраля 2011

Мне нужно понять кое-что очень важное относительно F #: как оно обрабатывает ссылки и значения.Я знаю, что F # определяет неизменяемые и изменяемые объекты, а также знаю причину этого.

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

То есть в C #, если у меня есть это:1008 *

Ну, а как насчет f #?

let myvar: MyObj = new MyObj ()
let myvar2: MyObj = myvar

Какова ситуация здесь?Задание включает в себя копию?или нет.

И вообще, какой f # подход к этой теме?(Я имею в виду значение против ссылки).

Ответы [ 2 ]

7 голосов
/ 13 февраля 2011

При работе со ссылочными типами и типами значений F # ведет себя так же, как C #.

  • Если у вас есть ссылочный тип, он работает со ссылкой на экземпляр в куче.
  • Если у вас есть тип значения (встроенный, объявленный в C # или объявленный в F # с использованием атрибута Struct),
    значение копируется, когда вы присваиваете ему другое значение или передаете в качестве аргумента.

Единственное заметное отличие состоит в том, что стандартные типы F # (различимые объединения, записи, списки, массивы и кортежи) имеют структурное равенство семантика. Это означает, что они сравниваются путем сравнения фактического значения, хранящегося в них, а не путем сравнения ссылок (даже если они являются ссылочными типами). Например, если вы создаете два списка кортежей, содержащих одинаковые данные, вы получаете:

> let l1 = [ ("Hello", 0); ("Hi", 1) ]
  let l2 = [ ("Hi", 1); ("Hello", 0) ] |> List.rev;;
(...)

> l1 = l2;;
val it : bool = true

Вы получаете true, хотя списки и кортежи являются ссылочными типами. Однако, если вы сравните ссылки ( РЕДАКТИРОВАТЬ: Добавлен образец, вдохновленный kvb ):

> System.Object.ReferenceEquals(l1, l2);;
val it : bool = false

Использование структурного равенства имеет смысл в F #, потому что типы неизменны - когда вы создаете два значения, содержащие одинаковые данные, они всегда будут одинаковыми. Если бы они были изменяемыми, вы могли бы изменить их, и они больше не были бы равными - поэтому имеет смысл использовать равенство ссылок для изменяемых типов.

6 голосов
/ 13 февраля 2011

Как вы можете убедить себя в следующем простом эксперименте, поведение F # такое же, как в C #:

printfn "%b" (myvar = myvar2)  // true

Или еще лучше:

printfn "%b" (obj.ReferenceEquals(myvar, myvar2)) // true

, поскольку, как указывает Томас, поведение (=) может быть немного тонким.

С моей точки зрения, на самом деле нет никакой логической альтернативы; что еще может содержать myvar2? Не существует какого-либо общего механизма для дублирования объектов произвольных типов, поэтому имеет смысл только то, что myvar и myvar2 содержат равные ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...