gpt4 book ai didi

f# - "only once"初始化后突变的惯用 F#?

转载 作者:行者123 更新时间:2023-12-04 21:16:39 25 4
gpt4 key购买 nike

在下文中,我定义 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 来传达:“null->object is ok, object -> object is forbidden”?

(很明显,我可以编写一个自定义的 set 函数来在运行时进行检查和抛出,但这似乎“聪明”多于有用,令人恼火。)

最佳答案

一旦库严重依赖继承,就很难避免通常的 OO 模式,即使您使用 F# 也是如此。因此,公平地说,我可能会编写与您所做的代码完全相同的代码,只是接受这样一个事实,即这部分代码不会那么漂亮(并在您所在的应用程序部分使用更多功能方法)没有被框架强制采用 OO 风格)。

另外,在这种情况下,我只接受 null - 你可以使用 option,但你没有得到任何好处,因为你不能做无论如何,如果值为 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 在它有 View 时调用您的函数,然后您的函数创建一个处理其他方法的新接口(interface) - 但您的接口(interface)仅在之后 一切都已正确初始化!

let vc = MyViewController(fun view ->
// Now we have valid 'view' so we construct animator!
let animator = UIDynamicAnimator(view)
{ new IInitializedView with
member x.OtherMethod() =
// no problem here, because we have animator...
animator.Whatever() })

但我对 Xamarin 的了解还不够多,无法判断这是否可以在更复杂的系统中正常工作。

关于f# - "only once"初始化后突变的惯用 F#?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32146540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com