【问题标题】:Write f# Function that takes parameterized constructor编写采用参数化构造函数的 f# 函数
【发布时间】:2014-05-17 21:10:16
【问题描述】:

我想编写一个从数据流创建对象的函数,例如

let nxL<'T  when 'T : (new : unit -> 'T)> (sr:StreamReader) = 
    let line = sr.ReadLine()
    if line <> null then 
        Some(new 'T(line))
    else
        None

但是,这不起作用,因为它失败了:

Calls to object constructors on typed parameters cannot be given arguments.

由于构造函数是函数,而 F# 是函数式语言,这对我来说毫无意义。有谁知道如何创建一个将类型作为参数并返回新实例的函数?

【问题讨论】:

标签: f#


【解决方案1】:

虽然像@scrwtp 建议的那样传递一个函数是一个很好的方法,但你想要的可能的:

let inline nxL (sr:StreamReader) = 
    let line = sr.ReadLine()
    if line <> null then 
        Some(^a : (new : string -> ^a) line)
    else
        None

【讨论】:

    【解决方案2】:

    您可以使用Activator.CreateInstance 创建一个给定类型的对象,但我认为从您发布的代码 sn-p 来看这不是绝对必要的。传递一个接受字符串并返回所需类型的对象的常规函数​​对您不起作用吗?如果你在乎的话,有点像工厂功能。像这样:

    let nxL<'T> (cons: string -> 'T) (sr:StreamReader) : 'T option = 
        let line = sr.ReadLine()
        if line <> null then 
            Some (cons line)
        else
            None
    

    此外,除了 StreamReader 之外,您实际上可以删除其上的所有类型注释,并且它将被推断为是通用的(保留它们以便清楚 sn-p 中发生了什么)。

    【讨论】:

    • 确实,这是我的工作,只是有一个函数其唯一目的是包装构造函数有点烦人。
    • 我想这是 F# 的一部分,必须适应现有的 .NET 生态系统。有趣的是,有区别的联合案例构造函数在这方面是“常规”函数,所以你可以直接在那里使用SomeUnion.SomeCase
    猜你喜欢
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 2012-09-18
    • 2016-03-05
    • 2022-09-23
    相关资源
    最近更新 更多