Попытка понять синтаксис определения класса F # - PullRequest
6 голосов
/ 11 февраля 2011

Я сейчас подхожу к занятиям по F # после того, как узнал много о самых важных особенностях этого языка.Что ж, синтаксис определения класса не прост для понимания, но некоторые из основных понятий теперь понятны мне, а другие нет.

1) Первое, что я хотел бы знать, это просто ПРАВИЛЬНО /НЕПРАВИЛЬНО.Я понял, что классы могут быть определены двумя способами:

  • Неявные классы.Эти классы имеют только один конструктор, и в первых строках класса необходимо определить, используя привязку let, все внутренние переменные, присваивая им значение.
  • Явные классы.Эти классы имеют много конструкторов.Они принимают, через привязку val, неинициализированные значения.Эти значения ДОЛЖНЫ БЫТЬ ИНИЦИАЛИЗИРОВАНЫ в конструкторах.Если конструктор не может определить значение хотя бы для одной из частных переменных, определенных с помощью привязки val, компилятор разозлится.

IS IT CORRECT ???

2)У меня проблема с пониманием синтаксиса конструктора в явных классах.Рассмотрим следующее:

Вот первая версия:

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

Вот вторая версия:

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

Вот последняя версия:

(* 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 {} *)

Я не понимаю, почему первые две версии компилируются, а третья, которая использует обычный синтаксис отступов, не делает этого.Эта проблема возникает только в конструкторах, потому что для членов я могу использовать синтаксис отступа

(* 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

Почему новой функции (конструктору) нужны {} скобки ?????Мне это не нравится, потому что кажется, что последовательность рассматривается.Более того, мой код также компилируется, когда в {} ракетках между одной инструкцией и другой точкой с запятой не вставляется.ПОЧЕМУ ????

Ответы [ 2 ]

3 голосов
/ 12 февраля 2011

Вы написали (выделение мое):

Неявные классы.Эти классы имеют только один конструктор , и в первых строках класса необходимо определить, используя привязку let, все внутренние переменные, присваивая им значение.

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

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

Чтобы создать конструкторprivate, вы можете написать

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

Затем вы можете использовать первичный конструктор просто как хороший способ инициализации всех полей.

2 голосов
/ 11 февраля 2011

Что касается 2), тело конструктора не похоже на тело типичной функции - оно имеет ограниченную синтаксическую форму, и в разделе { } оно может содержать только вызов родительского конструктора и присваивание полей (похоже на запись конструкции). При определении нормального члена вы не можете заключить отдельные выражения в { }, даже если бы захотели (то есть фигурные скобки не являются необязательными в этом контексте, они запрещены).

...