2011-02-11 15 views
6

Me estoy acercando ahora a las clases F # después de aprender mucho sobre las características más importantes de este lenguaje. Bueno, la sintaxis de definición de clase no es simple de entender, pero algunos de los conceptos principales ahora están claros para mí, pero otros no.Intentando comprender la sintaxis de definición de la clase F #

1) Lo primero que me gustaría saber es solo CORRECTO/NO CORRECTO. Comprendí que las clases se pueden definir de dos maneras:

  • Clases implícitas. Estas clases tienen solo un constructor, y en las primeras líneas de la clase, es necesario definir, usando el enlace let, todas las variables internas asignándoles un valor.
  • Clases explícitas. Estas clases tienen muchos constructores. Aceptan, a través del enlace val, valores no inicializados. Estos valores DEBEN SER INICIALIZADOS en los constructores. Si un constructor falla al definir un valor para al menos una de las variables privadas definidas utilizando el enlace val, el compilador se enojará.

IS IT CORRECT ???

2) Tengo un problema para entender la sintaxis para el constructor en clases explícitas. Considere lo siguiente:

Aquí está la primera versión:

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a; 
     myother = b; 
    } 

Aquí está la segunda versión:

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a (* No semicolon *) 
     myother = b (* No semicolon *) 
    } 

Aquí está la última versión:

(* DOES NOT COMPILE :(*) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = 
     myval = a (* Using the normal indent syntax, without {} *) 
     myother = b (* Using the normal indent syntax, without {} *) 

No entiendo por qué compilan las primeras dos versiones y la tercera, que usa las indentaciones regulares en sintaxis, no. Este problema se produce sólo en los constructores debido a los miembros que puedo utilizar la sintaxis guión

(* COMPILES :) *) 
type MyType = 
    val myval: int 
    val myother: int 
    (* Constructor *) 
    new (a: int, b: int) = { 
     myval = a (* No semicolon *) 
     myother = b (* No semicolon *) 
    } 
    (* Indentation accepted, no {} to be inserted *) 
    member self.mymember = 
     let myvar = myval 
     myvar + 10 

Por qué la nueva función (el constructor) necesita llaves {} ????? No me gusta, porque parece que se considera una secuencia. Además, mi código se compila también cuando, en las {} raquetas, entre una instrucción y la otra, no se inserta un punto y coma. ¿¿¿¿POR QUÉ????

+0

Lo siento AndryC por confundir el título ... Gracias por corregirlo :) – Andry

+0

Lo siento de nuevo por mi error ... gracias nyinyithann por corregir ... – Andry

+2

Esto no responde a su pregunta (ya que solo analizo la sintaxis implícita de clase)), pero quiero vincular esto en caso de que alguien encuentre esta pregunta solo en función de su título y esté buscando ayuda de sintaxis de clase general: http://lorgonblog.wordpress.com/2009/02/13/the-basic-syntax- of-f-classes-interfaces-and-members/ – Brian

Respuesta

2

En cuanto a 2), el cuerpo de un constructor no es como el cuerpo de una función típica - tiene una forma sintáctica restringida, y dentro de la sección { } solo puede contener una llamada al constructor padre y asignaciones de campos (similar a la construcción de registros). Al definir un miembro normal, no puede envolver las expresiones individuales en { } aunque lo desee (es decir, las llaves no son opcionales en este contexto, están prohibidas).

+0

OK ... Pensé en esto ... Gracias kvb :) – Andry

3

usted escribió (el énfasis es mío):

clases implícitas. Estas clases tienen un constructor solo, y en las primeras líneas de la clase, es necesario definir, usando el enlace let, todas las variables internas asignándoles un valor.

Eso no es cierto, puede usar la sintaxis implícita para definir la clase con múltiples constructores.De hecho, creo que es una buena idea usar la sintaxis de clase implícita casi siempre (porque simplifica las declaraciones). clases implícitas tienen una constructor principal que es la que se obtiene de forma implícita - este constructor debe tener el mayor número de parámetros (pero puede ser privado):

type Foo(a:int, b:int) = 
    do printfn "hello"   // additional constructor code 
    member x.Multiple = a * b // some members 
    new(x:int) = Foo(x, x)  // additional constructor 

Para hacer que el constructor privado, puede escribir

type Foo private (a:int, b:int) = 
    ... 

continuación, puede utilizar el constructor principal al igual que una buena manera de inicializar todos los campos.

Cuestiones relacionadas