2013-11-22 3 views
0

Итак, я занимаюсь исследованием интерфейсов на F #. Я нашел эти 2 статьи на нем. MSDN и F# for fun and profit Но, к сожалению, они только глубокие.F # Как использовать интерфейс в отдельном модуле

ОБНОВЛЕНО

вот мой модуль с моими интерфейсами

//open statements omitted for brevity 

module DrawingInterfaces = 

    ///gets a string representation of the SVG code representation of the object 
    type IRepresentable_SVG = 
     abstract member getSVGRepresenation : unit -> string 

//other interfaces omitted for brevity 

В настоящее время в том же пространстве имен и физической папке также у меня есть это:

type lineSet (x1off,x2off,y1off,y2off,x1,x2,y1,y2,rot,rotOff,count) = 

    //tons of member vals omitted for brevity 

    member val x1Start = x1 with get, set 

    interface DrawingInterfaces.IRepresentable_SVG with 
      member __.getSVGRepresenation() = 

       let mutable svg = "" 
       let mutable currentx1 = x1Start 
       svg 

Это используется, чтобы дать мне 2 ошибки, прежде чем я использовал __. обозначение для члена. Первая ошибка была на интерфейсной линии. И второй на линии участника. Ошибки были соответственно:

The type 'IRepresentable_SVG' is not defined 


This instance member needs a parameter to represent the object being invoked. 

Я был в состоянии установить первый, изменив порядок файла. Благодаря Джону Палмеру. Второй фиксированный./

После использования __. Обозначение Я смог избавиться от второй ошибки. Однако теперь появляется новая ошибка, когда я пытаюсь использовать члены типа в моей реализации интерфейса.

 let mutable currentx1 = x1Start 

x1Start показывает, что не определено. Мне нужно иметь возможность использовать значения, хранящиеся в моих других членах, в моей реализации.

+3

F # чувствителен к порядку составления файла. Файл определения над файлом использования в Visual Studio? –

+0

Изменение порядка компиляции задало первую проблему. –

ответ

3

Давайте сначала сделаем это, а затем укажем на ваши проблемы. Я определяю ниже 2 отдельных модулей в 2 отдельных .fs файлов в пределах одного пространства имен Example для интерфейса определения в модуль Example.DrawingInterfaces и интерфейс реализации в модуле Example.UseInterface, а также консольного приложения, которые будут использовать интерфейс от третьего модуля (implicit) Program. В моем проекте корреспондент кода файлы в следующем порядке: DefInterface.fs, UseInterface,fs, Program.fs (я также сделал несколько идиоматических изменения стиля и больше краткость пропуски)

Файл: DefInterface.fs

namespace Example 
module DrawingInterfaces = 
    type IRepresentable_SVG = 
     abstract member GetSVGRepresenation : unit -> string 

файлов : UseInterface.fs

namespace Example 
module UseInterface = 
    type LineSet (x1) = 
     member val X1Start = x1 with get, set 
     interface DrawingInterfaces.IRepresentable_SVG with 
      member __.GetSVGRepresenation() = "test" + " " + __.X1Start.ToString() 

Файл: Program.fs

open Example 
open System 

[<EntryPoint>] 
let main argv = 
    let lineSet = UseInterface.LineSet(5) 
    let example : DrawingInterfaces.IRepresentable_SVG = lineSet :> _ 
    example.GetSVGRepresenation() |> printfn "%A" 
    lineSet.X1Start <- 10 
    example.GetSVGRepresenation() |> printfn "%A" 
    0 

компилировать, запускать и убедитесь, что он работает.

Теперь проблемы в вашем коде:

  • первое сообщение об ошибке вытекающего из необходимости обращаться к полному реализованного имени интерфейса в UseInterface.fs, который Example.DrawingInterfaces.IRepresentable_SVG хотя оба модуля принадлежит одному и тому же пространству именам Example префикса может быть опущены
  • вторых точек сообщения об ошибке к необходимости использования экземпляра метода в классе реализации UseInterface.LineSet, что достигается добавление префикса self-identifier__. в подписи метода

Наконец, обратите внимание на использование вашего интерфейса в Program.fs, который импортирует пространство имен, обеспечивает имена модулей для определения и реализации соответственно, а также явное приведение реализации LineSet к IRepresentable_SVG.

EDIT: Я добавил X1Start свойство исходного LineSet, чтобы показать, как оно может быть использовано от реализации интерфейса каждого запроса сомнения автора. Теперь самоидентификатор __. более востребован и, вероятно, с использованием self. или даже this. вместо этого имеет смысл.

+0

Интересный выбор для самоидентификации :) – Jwosty

+0

Я родом из Java и недавно C# фона. Мне сложно определить или понять эту концепцию самоидентификации. Можете ли вы немного объяснить это или указать мне на статью, которая делает. На мой взгляд, имя метода было всего лишь именем метода. В интерфейсах C# или Java интерфейсы были очень простыми. Я полагаю, была достигнута определенная степень гибкости для увеличенной кривой обучения для интерфейсов F # и самоидентификации. –

+0

Здесь очень приятно [Q & A on self identifier] (http://stackoverflow.com/questions/5355334/what-are-the-benefits-of-such-flexible-self-identifiers-in-f) здесь, на SO вдоль с очень продуманными комментариями. Кроме того, он указывает, что при использовании self-id '__.' Имеет смысл. –

Смежные вопросы