所以我一直在研究F#上的接口。我发现了这两篇文章。 MSDN和F# 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显示为未定义。我需要能够在我的实现中使用存储在其他成员中的值。
答案 0 :(得分:3)
让我们先让它发挥作用然后指出你的问题。我在同一名称空间.fs
中的2个单独的Example
文件中定义了以下2个单独的模块,用于模块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
,尽管两个模块属于同一名称空间{可以省略{1}}前缀Example
中使用实例方法,这是通过将self-identifier UseInterface.LineSet
添加到方法签名<来实现的/ LI>
最后,请注意__.
中用于导入命名空间的接口的用法,分别为定义和实现提供模块名称,还明确地将实现Program.fs
强制转换为LineSet
。
编辑:我已将IRepresentable_SVG
属性添加到原始X1Start
,以显示如何根据问题作者的请求从界面实现中使用它。现在,自我身份LineSet
更加复杂,可能使用__.
甚至self.
会更有意义。