繁体   English   中英

在扩展递归方法 (F#) 中从 FOR ... IN 返回?

[英]Return from FOR … IN in extension recursive method (F#)?

我是 F# 的新手。 无法处理语法。 我需要将递归扩展方法从 C # 转换为 F #。 但无论我做什么,编译器都不喜欢我的代码。

这是我的方法:

 public static class ViewExtensions
    {

        public static UIView FindFirstResponder(this UIView view)
        {
            if (view.IsFirstResponder)
            {
                return view;
            }
            foreach (UIView subView in view.Subviews)
            {
                var firstResponder = subView.FindFirstResponder();
                if (firstResponder != null)
                    return firstResponder;
            }
            return null;
        }
    }

我试过这样的事情:

  type UIKit.UIView with
     member this.FindFirstResponder() =
        let mutable firstResponder = null
        if (this.IsFirstResponder) then this
        else
          for subView in this.Subviews do
             firstResponder <- subView.FindFirstResponder()

但这显然是不正确的,编译器不会跳过这一点。 任何人都可以帮忙吗?

F# 没有提前返回(这是 C# 中的return关键字正在做的事情)。 F# 中的每个表达式都必须从上到下进行全面评估,并且不能在中间中断。 来自类似 C 的语言可能会让人感觉很奇怪,但它实际上是一个特性,相信我。 它导致更易于理解、更易于维护的代码。

F# 中 model 迭代的自然方式是递归。 只要不进行递归调用,它就可以在任何步骤轻松中断。 但是您不必在每种情况下都使用裸递归,因为对于许多常见的用例,已经有库函数(它们本身是基于递归或其他此类函数构建的)。

在这种特殊情况下,感兴趣的 function 是Seq.tryPick 它采用序列和另一个 function,它返回一个option - SomeNone 然后Seq.tryPick将返回它遇到的第一个Some ,如果序列中没有Some ,则返回None 要将可为空的 .NET 值转换为option ,请使用Option.ofObj ,转换回使用Option.toObj

  type UIKit.UIView with
     member this.FindFirstResponder() =
        if this.IsFirstResponder then this
        else
          this.Subviews
          |> Seq.tryPick (fun v -> v.FindFirstResponder() |> Option.ofObj)
          |> Option.toObj

如果您必须与 C# 交互,这或多或少是您能做的最好的事情。 互操作总是有点难看。 但是,如果您不再需要 C#,我建议将IsFirstResponderSubviewsFindFirstResponder从方法和属性转换为独立函数,并使FindFirstResponder返回一个option (这是在 F# 中处理可选值的标准方法)。

然后 function 变得更漂亮了一点:

let findFirstResponder view =
  if isFirstResponder view then Some view
  else view |> subViews |> Seq.tryPick findFirstResponder

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM