F#如何在单独的模块中使用接口

时间:2013-11-22 05:21:19

标签: f#

所以我一直在研究F#上的接口。我发现了这两篇文章。 MSDNF# for fun and profit但不幸的是,它们只是肤浅。

已更新

这是我的接口模块

//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.

我能够通过更改文件顺序来修复第一个。感谢John Palmer。 第二个几乎是固定的./

使用__后。符号我能够摆脱第二个错误。但是,当我尝试在接口实现中使用类型成员时,会弹出一个新错误。

      let mutable currentx1 = x1Start

x1Start显示为未定义。我需要能够在我的实现中使用存储在其他成员中的值。

1 个答案:

答案 0 :(得分:3)

让我们先让它发挥作用然后指出你的问题。我在同一名称空间.fs中的2个单独的Example文件中定义了以下2个单独的模块,用于模块Example.DrawingInterfaces中的接口定义和接口实现在模块Example.UseInterface中以及一个控制台应用程序,它将使用来自第三个(implicit)模块Program的界面。在我的项目中,对应的代码文件按以下顺序排列:DefInterface.fsUseInterface,fsProgram.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 ,尽管两个模块属于同一名称空间{可以省略{1}}前缀
  • 第二条错误消息指出需要在实现类Example中使用实例方法,这是通过将self-identifier UseInterface.LineSet添加到方法签名<来实现的/ LI>

最后,请注意__.中用于导入命名空间的接口的用法,分别为定义和实现提供模块名称,还明确地将实现Program.fs强制转换为LineSet

编辑:我已将IRepresentable_SVG属性添加到原始X1Start,以显示如何根据问题作者的请求从界面实现中使用它。现在,自我身份LineSet更加复杂,可能使用__.甚至self.会更有意义。