F# 相当于 Kotlin 的 ?。操作员

F# equivalent to Kotlin's ?. operator

我刚开始我的第一个 F# 项目,来自 JVM 世界,我非常喜欢 Kotlin 的可空性语法,并且想知道如何在 F# 中实现类似的紧凑语法。

这是一个例子:

class MyClass {
    fun doSomething() {
        // ...
    }
}

// At some other place in the code:
val myNullableValue: MyClass? = null
myNullableVallue?.doSomething()

这是做什么的:

  1. 如果myNullableValue不是null,即有一些数据,doSomething()在那个对象上被调用。
  2. 如果 myNullableValuenull(如上面的代码),什么也不会发生。

据我所知,F# 等效项是:

type MyClass = 
    member this.doSomething() = ()

type CallingCode() = 
    let callingCode() = 
        let myOptionalValue: MyClass option = None
        match myOptionalValue with 
        |Some(x) -> x.doSomething()
        |None -> ()

在 Kotlin 中 1 行长的语句在 F# 中是 3 行长。因此,我的问题是是否有更短的语法来完成同样的事情。

目前 F# 中没有用于执行此操作的内置运算符。我怀疑原因是在 F# 中使用未定义值的频率较低。例如,您永远不会定义一个变量,将其初始化为 null,然后有一些代码可能会或可能不会将其设置为 F# 中的值,因此通常编写 F# 的方式消除了对此类的许多需求运算符。

有时您仍然需要这样做,例如当使用 option 来表示可以合法丢失的内容时,但我认为这种情况不如其他语言那么频繁。在与 .NET 交互时,您也可能需要这样的东西,但是在做任何其他事情之前先处理 null 可能是一个很好的做法。

除了模式匹配之外,您还可以使用 Option.map 或 F# 计算表达式(没有标准表达式,但使用库或定义库很容易 - 请参阅 for example)。那么你可以这样写:

let myOptionalValue: MyClass option = None

// Option #1: Using the `opt` computation expression
opt { let! v = myOptionalValue 
      return v.doSomething() }

// Option #2: Using the `Option.map` function
myOptionalValue |> Option.map (fun v -> v.doSomething() )

作为参考,我对opt的定义是:

type OptionBuilder() =
  member x.Bind(v,f) = Option.bind f v
  member x.Return v = Some v
  member x.ReturnFrom o = o
  member x.Zero () = None

let opt = OptionBuilder()

那个?。已建议将运算符添加到 F#。

https://github.com/fsharp/fslang-suggestions/issues/14

总有一天会添加的,我希望很快。