【问题标题】:F# treating internal module as privateF# 将内部模块视为私有模块
【发布时间】:2011-11-11 11:10:46
【问题描述】:

任何想法为什么以下不编译?

在最后一行它告诉我 Module1 没有定义。如果我从 Module1 中删除“内部”,它可以正常工作。

我有两个代码文件,Module1.fs在项目中的Module2.fs之上。

模块1.fs

module internal Module1

let sample =
    5 + 4

模块2.fs

module Module2

let sample2 =
    3 + Module1.sample

【问题讨论】:

    标签: .net f# module visibility


    【解决方案1】:

    这应该是命名空间问题。 只需在两个文件的顶部添加命名空间定义(相同的命名空间!),如下所示:

    namespace MyNamespace
    
    module internal Module1 =
    
    let sample = 5+4
    

    namespace MyNamespace
    
    module Module2 =
    
    let sample2 = 3 + Module1.sample
    

    【讨论】:

    • 这不会编译,因为该模块是一个本地模块,但想法是正确的 - Daniel 的解决方案有效。
    • 否 - 这没有编译,因为我忘记了“=”(我不时会发生这种情况) - 解决方案与 Daniels 并没有非常不同。 ...确保我只是逐行测试了这个 code ...它肯定不是一些“本地”问题 - 它按预期工作。当然你应该在那里插入一些有意义的命名空间
    • “=”符号是必需的,因为命名空间内的模块定义是本地模块,我不是特别想使用它 - 这不是“本地”问题,而是 F# 语言的区别,见msdn.microsoft.com/en-us/library/dd233221.aspx
    • 好的——你的选择——请问为什么?缩进?当我阅读您的链接文章时,它几乎毫无用处:“如果您在一个项目或单个编译中有多个文件,或者如果您正在构建一个库,则必须在文件顶部包含命名空间声明或模块声明”
    • 我不认为这有什么大不了的,但使用顶级模块声明似乎更简单。是的,缩进整个模块会有点烦人。无论如何,谢谢你的帮助。
    【解决方案2】:

    您需要为您的模块提供一个命名空间,以便以后的模块可以看到 internal 模块。

    let module internal MyNamespace.Module1
    let module MyNamespace.Module2
    

    【讨论】:

    • 对于较大的项目,我建议在最后省略可访问性修饰符,然后添加签名文件来处理它。
    • 我感觉很奇怪。为什么我们需要另一个命名空间来使 internal 正常工作?
    【解决方案3】:

    编译器错误

    虽然这里的答案是解决方法,但这种行为仍然是编译器错误。阅读文档和 Don Syme 的 Expert F#,没有一点说内部模块中的类型只有在您还使用命名空间时才能访问

    考虑到编译器发出的代码,我认为使内部模块中的类型在程序集中可见并不困难。

    编辑: 将这种行为提交给@fsbugs 后,主人本人 Don Syme 很快确认这是一个错误。我为此案例添加了一个工作项:

    https://visualfsharp.codeplex.com/workitem/29

    【讨论】:

    • 如果您认为这是一个错误,您是否已向 fsbugs@microsoft.com 或 visualfsharp.codeplex.com 提交了错误报告?
    猜你喜欢
    • 2017-10-17
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2020-10-13
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多