[Перевод] F#7: Записи (Records)
Итак, мы продолжаем наше путешествие к большему количеству типов F#. На этот раз мы рассмотрим типы Записей.
Как мне создать запись
Когда вы создаете новую запись F#, она может напоминать вам анонимные объекты в C #. Вот как вы их создаете. Я думаю, что они очень похожи на анонимные объекты в C#, поэтому, если вы использовали C#, записи F# не должны быть сложными.
Все начинается с создания нового типа для записи. Определение типа перечисляет имя свойств, а также тип свойств, это можно увидеть ниже.
Если у вас есть определение типа записи, вы можете связать новый экземпляр со значением, используя Let. Снова пример этого можно увидеть ниже, где мы связываем новую запись, используя привязку Let, и мы также печатаем значения свойств экземпляра записи в вывод консоли.
type Person = { Age : int; Sex: string; Name:string; }
....
....
....
....
let sam = { Age = 12; Sex="Male"; Name ="Sam" }
printfn "let sam = { Age = 12; Sex=\"Male\"; Name=\"Sam\" }"
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.Name
Как я могу изменить / клонировать запись
Вы можете клонировать и изменить запись, что обычно делается следующим образом:
let sam = { Age = 12; Sex="Male"; Name ="Sam" }
let tom = { sam with Name="Tom" }
printfn "let tom = { sam with Name=\"Tom\" }"
printfn "Person with Age is %i and Sex is %s and Name is %s" tom.Age tom.Sex tom.Name
Обратите внимание, как мы использовали ключевое слово «with» при создании нового экземпляра Tom Person. Эта форма выражения записи называется »копировать и обновлять выражение записи». Другой вариант, который вы можете использовать (опять же, мы поговорим об этом более подробно в следующем посте), это использовать изменяемое свойство в вашем типе записи. Записи являются неизменяемыми по умолчанию; однако вы также можете явно указать изменяемое поле.
Вот пример, обратите внимание, как я создал новый тип, который имеет изменяемое свойство с именем MutableName. Определяя изменяемое поле, мне разрешено обновлять значение свойства MutableName записи, что вы можете сделать с помощью оператора »<-». Что просто позволяет назначать новое значение.
type MutableNamePerson = { Age : int; Sex: string; mutable MutableName:string; }
....
....
....
....
//create
let sam = { Age = 12; Sex="Male"; MutableName ="Sam" }
printfn "let sam = { Age = 12; Sex=\"Male\"; Name=\"Sam\" }"
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.MutableName
//update
sam.MutableName <- "Name changed"
printfn "sam.MutableName <- \"Name changed\""
printfn "Person with Age is %i and Sex is %s and Name is %s" sam.Age sam.Sex sam.MutableName
Сравнение Записей
Типы записей равны, только если ВСЕ свойства считаются одинаковыми. Вот пример:
type Person = { Age : int; Sex: string; Name:string; }
....
....
....
....
let someFunction p1 p2 =
printfn "p1=%A, and p2=%A, are they equal %b" p1 p2 (p1=p2)
let sam = { Age = 12; Sex = "Male"; Name = "Sam" }
let john = { Age = 12; Sex = "Male"; Name = "John" }
let april = { Age = 35; Sex = "Female"; Name = "April" }
let sam2 = { Age = 12; Sex = "Male"; Name = "Sam" }
do someFunction sam john
do someFunction sam april
do someFunction sam sam2
Паттерны сравнения записей
Конечно, можно использовать сопоставление с образцом (обсуждение на другой день), который является основным методом F#, для сопоставления с типами записей. Вот пример:
type Person = { Age : int; Sex: string; Name:string; }
.....
.....
.....
.....
let someFunction (somePerson :Person) =
match somePerson with
| { Name="Sam" } -> printfn "Sam is in the house"
| _ -> printfn "you aint Sam, get outta here clown"
let sam = { Age = 12; Sex="Male"; Name ="Sam" }
let john = { Age = 12; Sex="Male"; Name ="John" }
do someFunction sam
do someFunction john
Методы и свойства
Также возможно добавить дополнительных членов к записям. Вот пример, где мы добавляем свойство «Details», чтобы позволить получить полную информацию о записи, используя одно свойство (столько, сколько мы могли бы достичь, переопределяя метод ToString (), но более подробно о методах OOП позже)
Обратите внимание, что если вы попытаетесь добавить элемент в определение типа записи, как показано на снимке экрана, вы получите странную ошибку
Это легко решить, просто поместив определения свойств записи в новую строку, и убедившись, что элемент также начинается с новой строки, и наблюдайте за этим отступом (пробелом), так как все это важно в F#:
type Person =
{ Age : int; Sex: string; Name:string; }
member this.Details = this.Age.ToString() + " " + this.Sex.ToString() + " " + this.Name
....
....
....
....
let sam = { Age = 12; Sex = "Male"; Name = "Sam" }
printfn "sam Details=%s" sam.Details