F# 等效于 Kotlin 的 ?。算子

F# equivalent to Kotlin's ?. operator

提问人:vatbub 提问时间:6/16/2021 更新时间:6/19/2021 访问量:176

问:

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

下面是一个示例:

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

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

其作用:

  1. 如果不是,即有一些数据,则在该对象上调用。myNullableValuenulldoSomething()
  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 行的 stamement 在 F# 中长 3 行。因此,我的问题是,是否有一种更短的语法可以满足同样的事情。

Kotlin F#

评论

0赞 Sweeper 6/16/2021
请参阅此讨论

答:

5赞 Tomas Petricek 6/16/2021 #1

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

有时您仍然需要这样做,例如,当用于表示可以合法地丢失的东西时,但我认为这比其他语言更不常见。在与 .NET 交互时,您可能还需要这样的东西,但最好先处理 s,然后再执行任何其他操作。optionnull

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

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()

评论

1赞 Bent Tranberg 6/16/2021
我相信你会使用而不是问题中的函数,它返回.或者,用于更通用的样式。Option.iterOption.mapunit|> ignore
1赞 Tomas Petricek 6/16/2021
@BentTranberg 你是对的 - 是副作用计算的方法!(这也许也是以不需要和副作用的方式编写代码的另一个原因!iternulls
0赞 vatbub 6/16/2021
当然,将值设置为 在 Kotlin 中也是不合适的,这只是为了示例。我的用例是那些可能合法没有数据的用例之一。不过还有一个问题:为什么我需要这个块?我不能简单地通过管道进入吗?nulloptmyOptionalVAlueOption.map
0赞 Tomas Petricek 6/16/2021
@vatbub 很抱歉造成混淆,您不需要它。这应该是做同样事情的两种替代选择。我在回答中澄清了这一点。
0赞 vatbub 6/16/2021
啊,在那种情况下,我可能会走这条路。我会将您的答案标记为解决方案。谢谢:)Option.map
2赞 citykid 6/17/2021 #2

这?。已建议将运算符添加到 F# 中。

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

我希望有一天它会被添加。