习惯性F#仅用于#34;只有一次"初始化后的突变?

时间:2015-08-21 17:54:05

标签: f# functional-programming

在下文中,我定义Animator的方式在OOP系统中很常见,可以认为改变this对象的状态是正确的:

type MyViewController() = 
    inherit UIViewController() 

    //Is there a better way than this?
    member val Animator = null with get, set 

    override this.ViewDidLoad() = 
        base.ViewDidLoad()

        //this.View is defined in base class and is only valid *now*
        this.Animator <- new UIDynamicAnimator(this.View) 

是否有更惯用的方式来定义Animator进行通信:&#34; null - &gt;对象正常,对象 - &gt;对象被禁止&#34;?

(显然,我可以编写一个在运行时检查和抛出的自定义set函数,但这似乎更令人讨厌,而且非常有用而且非常有用。)

2 个答案:

答案 0 :(得分:4)

一旦库非常依赖继承,即使你使用F#,也很难避免通常的OO模式。所以公平地说,我可能会编写与您所做的完全相同的代码,并且只是考虑到这部分代码不会那么漂亮(并且在应用程序的某些部分中使用更多功能方法)没有被框架强制进入OO风格)。

另外,在这种情况下,我只使用null - 您可以使用option,但是您没有获得任何好处,因为如果值为{,您将无法做多少工作{1}}无论如何。

据推测,在您的完整源代码中,您将覆盖该类的其他方法,并且您正在创建None,以便可以在其他方法中使用它。你可以做的一件事是从类中提取代码并编写如下代码:

Animator

这里的想法是type IInitializedView = abstract OtherMethod : UIViewController -> unit type MyViewController(viewInitialized:UIView -> IInitializedView) = inherit UIViewController() let mutable initializedView = None override this.ViewDidLoad() = base.ViewDidLoad() initializedView := Some(viewInitialized this.View) override this.OtherMethod() = viewInitialized |> Option.iter (fun vi -> vi.OtherMethod() ) 在它有视图时调用你的函数,然后你的函数创建一个处理另一个方法的新接口 - 但你的接口只在之后创建正确初始化!

MyViewController

但是我不太了解Xamarin是否可以在一个更复杂的系统中运行。

答案 1 :(得分:3)

我认为@Carsten得到的是你不应该引入空值,除非你绝对被迫与其他CLI语言互操作。在F#中声明的类型无论如何都不允许它们,除非用Option<'a>装饰。

type MyViewController() = inherit UIViewController() let mutable animator = Option<UIDynamicAnimator>.None member x.Animator = animator.Value override this.ViewDidLoad() = base.ViewDidLoad() animator <- Some <| new UIDynamicAnimator(this.View) 类型中包含的值将是一种直接的翻译,但仍具有可变性。我假设您不需要属性设置器,将自动属性替换为let-bound值。

Lazy<'a>

另一方面,在type MyViewController() as this = inherit UIViewController() let animator = lazy(new UIDynamicAnimator(this.View)) member x.Animator = animator.Value override this.ViewDidLoad() = base.ViewDidLoad() // Optional; only if you need the object creation right now animator.Force() |> ignore 中包装更具功能性。

{{1}}