Campos explícitos: O val palavra-chave (F#)
O val palavra-chave é usada para declarar um campo em um tipo de classe ou estrutura sem inicializar o proprietário. Campos declarados dessa maneira são chamados de campos explícitos.
[ static ] val [ mutable ] [ access-modifier ] field-name : type-name
Comentários
A maneira usual de definir campos em um tipo de classe ou estrutura é usar um let de vinculação. No entanto, let ligações devem ser inicializadas como parte do construtor de classe, que é sempre não é possível, é necessário, ou desejável. Você pode usar o val palavra-chave quando desejar que um campo que não foi inicializado.
Campos de explícitos podem ser estáticas ou non-static. The access-modifier can be public, private, or internal. Por padrão, os campos explícitos são públicos. Isso difere do let ligações em classes, que são sempre particulares.
O ValorPadrão atributo é necessário nos campos explícitos em tipos de classe que tem um construtor primário. Este atributo especifica que o campo é inicializado para zero. O tipo do campo deve oferecer suporte a inicialização do zero. Um tipo oferece suporte a inicialização de zero se for um dos seguintes:
Um tipo primitivo que tem um valor zero.
Um tipo que oferece suporte a um valor nulo, como um valor normal, como um valor de anormal ou como uma representação de um valor. Isso inclui classes, tuplas, registros, funções, interfaces.Tipos de referência do NET, o unit o tipo e tipos de união discriminada.
A.Tipo do valor líquido.
Uma estrutura cujos campos todos os suportam padrão de valor zero.
O código a seguir mostra o uso de campos explícitos e, para comparação, uma let a ligação em uma classe que tem um construtor primário. Observe que o let-campo acoplado myInt1 é privado. Quando o let-campo acoplado myInt1 é referenciado a partir de um método de membro, o identificador de auto- this não é necessária. Mas quando você está fazendo referência explícitos campos myInt2 e myString, o identificador de auto-é necessário.
type MyType() =
let mutable myInt1 = 10
[<DefaultValue>] val mutable myInt2 : int
[<DefaultValue>] val mutable myString : string
member this.SetValsAndPrint( i: int, str: string) =
myInt1 <- i
this.myInt2 <- i + 1
this.myString <- str
printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)
let myObject = new MyType()
myObject.SetValsAndPrint(11, "abc")
// The following line is not allowed because let bindings are private.
// myObject.myInt1 <- 20
myObject.myInt2 <- 30
myObject.myString <- "def"
printfn "%d %s" (myObject.myInt2) (myObject.myString)
A saída é o seguinte:
11 12 abc
30 def
O código a seguir mostra o uso de campos explícitos em uma classe que não tem um construtor primário. Nesse caso, o DefaultValue atributo é não necessário, mas todos os campos devem ser inicializados em construtores de que são definidos para o tipo.
type MyClass =
val a : int
val b : int
// The following version of the constructor is an error
// because b is not initialized.
// new (a0, b0) = { a = a0; }
// The following version is acceptable because all fields are initialized.
new(a0, b0) = { a = a0; b = b0; }
let myClassObj = new MyClass(35, 22)
printfn "%d %d" (myClassObj.a) (myClassObj.b)
A saída é 35 22.
O código a seguir mostra o uso de campos explícitos em uma estrutura. Como uma estrutura é um tipo de valor, ele automaticamente tem um construtor padrão que define os valores de seus campos como zero. Portanto, o DefaultValue o atributo não é necessário.
type MyStruct =
struct
val mutable myInt : int
val mutable myString : string
end
let mutable myStructObj = new MyStruct()
myStructObj.myInt <- 11
myStructObj.myString <- "xyz"
printfn "%d %s" (myStructObj.myInt) (myStructObj.myString)
A saída é 11 xyz.
Campos explícitos não são destinados ao uso de rotina. Em geral, quando possível deve usar um let a ligação em uma classe em vez de um campo de explícito. Os campos explícitos são úteis em determinados cenários de interoperabilidade, como, por exemplo, quando você precisa definir uma estrutura que será usada em uma plataforma chamar chamadas para uma API nativa ou em cenários de interoperabilidade COM. Para obter mais informações, consulte Funções externas (F#). Outra situação em que um campo de explícito talvez seja necessário é quando você estiver trabalhando com um gerador de código F# que emite classes sem um construtor primário. Campos explícitos também são úteis para variáveis de thread estático ou construções semelhantes. Para obter mais informações, consulte ThreadStaticAttribute.
Consulte também
Referência
Deixe as ligações de Classes (F#)