Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Структура — это компактный тип объекта, который может быть более эффективным, чем класс для типов с небольшим объемом данных и простым поведением.
Синтаксис
[ attributes ]
type [accessibility-modifier] type-name =
struct
type-definition-elements-and-members
end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
type-definition-elements-and-members
Замечания
Структуры — это типы значений, что означает, что они хранятся непосредственно в стеке или, когда они используются в качестве полей или элементов массива, встроенные в родительский тип. В отличие от классов и записей, структуры имеют семантику сквозного значения. Это означает, что они полезны в первую очередь для небольших статистических выражений данных, к которым часто обращаются и копируются.
В предыдущем синтаксисе показаны две формы. Первый — это не упрощенный синтаксис, но он, тем не менее, часто используется, так как при использовании struct ключевых end слов и ключевых слов можно опустить StructAttribute атрибут, который отображается во второй форме. Вы можете просто сократить StructAttributeStruct.
Тип-definition-elements-and-members в предыдущем синтаксисе представляет объявления и определения элементов. Структуры могут иметь конструкторы и изменяемые и неизменяемые поля, и они могут объявлять элементы и реализации интерфейса. Дополнительные сведения см. в разделе "Участники".
Структуры не могут участвовать в наследовании, не могут содержать let или do привязки и не могут рекурсивно содержать поля собственного типа (хотя они могут содержать ссылочные ячейки, ссылающиеся на свой собственный тип).
Так как структуры не допускают let привязки, необходимо объявить поля в структурах с помощью ключевого val слова. Ключевое val слово определяет поле и его тип, но не разрешает инициализацию. Вместо этого val объявления инициализированы до нуля или null. По этой причине структуры, имеющие неявный конструктор (т. е. параметры, которые задаются сразу после имени структуры в объявлении), требуют val аннотации объявлений атрибутом DefaultValue . Структуры с определенным конструктором по-прежнему поддерживают нулевое инициализацию. Таким образом, атрибут является объявлением о том, DefaultValue что такое нулевое значение допустимо для поля. Неявные конструкторы для структур не выполняют никаких действий, так как let и do привязки не допускаются для типа, но значения параметров неявного конструктора, передаваемые в них, доступны как закрытые поля.
Явные конструкторы могут включать инициализацию значений полей. Если у вас есть структура с явным конструктором, она по-прежнему поддерживает нулевое инициализацию; Однако атрибут не используется DefaultValue в val объявлениях, так как он конфликтует с явным конструктором. Дополнительные сведения о объявлениях см. в valразделе "Явные поля: ключевое val слово".
Атрибуты и модификаторы специальных возможностей разрешены в структурах и соответствуют тем же правилам, что и для других типов. Дополнительные сведения см. в разделе "Атрибуты " и "Управление доступом".
В следующих примерах кода показаны определения структуры.
// In Point3D, three immutable values are defined.
// x, y, and z will be initialized to 0.0.
type Point3D =
struct
val x: float
val y: float
val z: float
end
// In Point2D, two immutable values are defined.
// It also has a member which computes a distance between itself and another Point2D.
// Point2D has an explicit constructor.
// You can create zero-initialized instances of Point2D, or you can
// pass in arguments to initialize the values.
type Point2D =
struct
val X: float
val Y: float
new(x: float, y: float) = { X = x; Y = y }
member this.GetDistanceFrom(p: Point2D) =
let dX = (p.X - this.X) ** 2.0
let dY = (p.Y - this.Y) ** 2.0
dX + dY |> sqrt
end
Структуры ByRefLike
Вы можете определить собственные структуры, которые могут соответствовать byrefсемантике: дополнительные сведения см. в разделе Byrefs . Это делается с помощью атрибута IsByRefLikeAttribute:
open System
open System.Runtime.CompilerServices
[<IsByRefLike; Struct>]
type S(count1: Span<int>, count2: Span<int>) =
member x.Count1 = count1
member x.Count2 = count2
IsByRefLike не подразумевает Struct. Оба должны присутствовать в типе.
Структуру типа "byrefкак" в F# — это тип значения, привязанного к стеку. Он никогда не выделяется в управляемой куче. Например byref, структуру полезно для высокопроизводительного программирования, так как она применяется с набором надежных проверок времени существования и без отслеживания. Ниже приведены правила.
- Их можно использовать в качестве параметров функции, параметров метода, локальных переменных, возвращаемого методом.
- Они не могут быть статическими или экземплярами элементов класса или обычной структуры.
- Они не могут быть захвачены какой-либо конструкцией закрытия (
asyncметодами или лямбда-выражениями). - Их нельзя использовать в качестве универсального параметра.
Хотя эти правила очень сильно ограничивают использование, они делают это для выполнения обещания высокопроизводительных вычислений безопасным образом.
Структуры ReadOnly
Вы можете замечать структуры с помощью атрибута IsReadOnlyAttribute . Рассмотрим пример.
[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
IsReadOnly не подразумевает Struct. Необходимо добавить оба элемента, чтобы иметь структуру IsReadOnly .
Использование этого атрибута выдает метаданные, позволяя F# и C# знать, как и inref<'T>in refсоответственно.
Определение изменяемого значения внутри структуры чтения создает ошибку.
Структуры записей и дискриминированных профсоюзов
Вы можете представлять записи и дискриминированные профсоюзы в виде структур с атрибутом [<Struct>] . Дополнительные сведения см. в каждой статье.