Rubyでmixinを実現する方法やF#でScalaの特性を得る方法はありますか?mixin or trait in F#
私が望むのは、基本的にあるモジュールを別のモジュールにコピーして他のモジュールの機能を共有することですが、変更はできません。または、OOPの考え方では、親オブジェクトを変更できないことを除いて、複数の継承が必要です。
Rubyでmixinを実現する方法やF#でScalaの特性を得る方法はありますか?mixin or trait in F#
私が望むのは、基本的にあるモジュールを別のモジュールにコピーして他のモジュールの機能を共有することですが、変更はできません。または、OOPの考え方では、親オブジェクトを変更できないことを除いて、複数の継承が必要です。
あなたはアヒルを行うにはinline
とメンバー制約を乱用することができますミックスインの利点のいくつかを得るタイピング。これに
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
:
type Phonograph(id, name) =
member x.Id : int = id
override x.ToString() = name
type EightTrack(id, name) =
member x.Id : int = id
override x.ToString() = name
module Debug =
let inline whoAmI x =
sprintf "%s (%d) : %s"
(^T : (member GetType : unit -> Type) x).Name
(^T : (member Id : int with get) x)
(^T : (member ToString : unit -> string) x)
let ph = Phonograph(537766170, "West End Blues")
let et = EightTrack(537765860, "Surrealistic Pillow")
Debug.whoAmI ph //"Phonograph (537766170) : West End Blues"
Debug.whoAmI et //"EightTrack (537765860) : Surrealistic Pillow"
それは必要としないの拡張メソッドの上に(議論の余地)利点があるたとえば、(this tutorialから取られた)このRubyコードを変換することができ共通基本クラスまたはインタフェースopen
キーワードについての以前の質問に関しては、whoAmI
を定義するいくつかのモジュールを持つことができ、最後にopen
が1つ前のモジュールをシャドウします。そのようにして、あなたが望むモジュールを「ミックスイン」することができます。 F#コアライブラリはchecked operatorsで同様のアプローチを使用します。
Rubyミックスインは、.NET Frameworkの拡張メソッド(型拡張子)で最もよくエミュレートされます。私は、F#にミックスイン、形質、または複数の継承に酷似した特別な言語機能があるとは思わない。
この質問を参照してください:How do I create an extension method (F#)?
そしてこの説明:スピードの便宜上http://msdn.microsoft.com/en-us/library/dd233211.aspx
は、ここにMSDNに与えられた例を示します
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
// Define type extension.
type MyClass with
member this.G() = 200
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
多少の関連性:http://stackoverflow.com/q/1805473/162396 – Daniel