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

vat*_*bub 3 f# kotlin

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

下面是一个例子:

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

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

这是做什么的:

  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 -> ()
Run Code Online (Sandbox Code Playgroud)

在 Kotlin 中长度为 1 行的雄蕊在 F# 中为 3 行。因此,我的问题是是否有更短的语法可以完成同样的事情。

Tom*_*cek 5

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

有时您仍然需要这样做,例如在option用于表示可能合法丢失的东西时,但我认为这比其他语言中的频率要低。在与 .NET 交互时,您可能也需要类似的东西,但是null在做任何其他事情之前先处理s可能是一个好习惯。

除了模式匹配之外,您还可以使用Option.mapF# 计算表达式(没有标准的表达式,但使用库或定义一个库很容易——参见示例)。然后你可以写:

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() )
Run Code Online (Sandbox Code Playgroud)

作为参考,我的定义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()
Run Code Online (Sandbox Code Playgroud)