【问题标题】:Convert out parameter of constructor to a tuple to use in pattern matching in F#将构造函数的输出参数转换为元组以用于 F# 中的模式匹配
【发布时间】:2011-08-13 02:40:45
【问题描述】:

have read 认为 F# 足够聪明,可以将方法的参数转换为元组。例如:

let isInt s =
  match System.Int32.TryParse(s) with
  | (false, _) -> false
  | (true, _) -> true

我想创建一个具有唯一系统范围名称的新互斥锁。有一个带有 3 个参数的构造函数:

new: 
    initiallyOwned:bool * 
    name:string * 
    createdNew:bool byref -> Mutex

最后一个参数是out参数,F#应该能够将构造函数调用结果转换为元组。 然而,以下代码看起来无法编译并出现错误“此表达式应具有 Mutex 类型,但此处具有类型 'a * 'b

open System.Threading

let rec CreateUniqueMutex i =
    match new Mutex(false, i.ToString()) with
    | (_, false) -> CreateUniqueMutex (i+1) // Error here
    | (mutex, true) -> mutex

和第一个isInt方法有什么区别?

我的代码可以修复吗?

最适合我的任务的代码是什么?

【问题讨论】:

    标签: f# pattern-matching


    【解决方案1】:

    不同之处在于Mutex 构造函数有多个重载,因此编译器认为您调用的重载正好采用两个参数。你最好的办法是声明一个可变的本地并使用它:

    let rec createUniqueMutex i =
        let mutable b = false
        let mutex = new Mutex(false, string i, &b)
        if b then mutex else createUniqueMutex (i+1)
    

    请注意,我已经修复了您的代码的一些其他问题。特别是需要使用let rec来定义一个递归函数,并且需要给(i+1)加上括号。

    编辑

    只是为了表明如果不是因为重载,这将起作用:

    type MyType(x:string, [<System.Runtime.InteropServices.Out>]y:int byref) =
        do y <- 3
        member __.X = x
    
    let (myT, n) = MyType("test")
    

    作为一个小问题,请注意 match 语句中的元组是向后的:返回值在前,所以它们应该是 (_,false)(mutex, true)

    【讨论】:

    • 有什么方法可以提示编译器使用带有 3 个参数的构造函数?
    • @Konstantin - 据我所知。
    • @kvb:不应该是(false, _)(true, mutex)吗?
    • 你知道为什么(System.Console.Write : string -&gt; unit)(value) 被允许,而(new Mutex : bool * string * bool -&gt; Mutex)(false, i.ToString()) 不允许吗?
    • @Daniel - 这是一致的;在 TryGetValue 的情况下,返回值是指示成功/失败的布尔值,输出参数是值;在 Mutex 构造函数中,返回值是互斥体,输出参数是指示成功/失败的布尔值。无论哪种情况,返回值首先出现在元组中。
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2012-04-29
    • 1970-01-01
    • 2019-08-28
    相关资源
    最近更新 更多