【问题标题】:Why adding some packages breaks my code?为什么添加一些包会破坏我的代码?
【发布时间】:2017-12-04 17:53:51
【问题描述】:

我注意到添加包有时会破坏我的代码。像 Seq.replicateList.take 这样工作的函数会出现红色波浪线,并且程序不再运行。这是应该复制问题的详细过程(我正在使用VS Community Edition 2017):

1) 创建一个项目。

2) Program.fs 包含代码:

[<EntryPoint>]
let main argv =
    printfn "%A" argv
    0 // return an integer exit code

3) 添加如下两行代码:

[<EntryPoint>]
let main argv =
    let repla = Seq.replicate 10 "A"
    printfn "%A" (repla |> List.ofSeq |> List.take 5)
    printfn "%A" argv
    0 // return an integer exit code

3) 点击Ctrl+F5,程序运行没有任何问题。

4) 在Solution Explorer 上右键单击References。点击Manage Nuget Packages...

5) 点击Browse

6) 搜索Newtonsoft.Json并安装。

7) 点击Ctrl+F5,程序运行没有任何问题。控制台打印

["A"; "A"; "A"; "A"; "A"]
[||]

8) 按照步骤 4 到 6 进行操作,并使用 Nuget 安装包 MathNet.Numerics

9) 点击Ctrl+F5,程序运行没有任何问题。控制台打印

["A"; "A"; "A"; "A"; "A"] [||]

10) 按照步骤 4 到 6 进行操作,并使用 Nuget 安装包 MathNet.Numerics.FSharp

11) 点击Program.fs 标签。可怕的红色波浪线出现在 Seq.replicateandList.take` 下。

12) 点击Ctrl+F5。将弹出一个对话框,其中包含以下消息:

There were build errors. Would you like to continue and run the last successful build?

问题:

a) 到底发生了什么?

b) 这是与MathNet.Numerics.FSharp 中的问题或安装的特定软件包组合或安装顺序有关的孤立案例吗?或者这是一个普遍的问题?

c) 使用 Nuget 时是否可以避免这个问题?

d) 如果没有,是否可以通过其他方式(不是 Nuget)安装来避免这个问题?

【问题讨论】:

  • 你安装的是什么版本的包?
  • (1)红色波浪线下的错误是什么? (2) 您是否注意到安装MathNet.Numerics.FSharp 是否导致安装任何other 包(由于是传递依赖)?
  • @FyodorSoikin - 红色波浪下方的错误是The value, constructor, namespace or type 'replicate'is not defined。当安装MathNet.Numerics.FSharp 时,它也会安装FSharp.Core.3.1.2.5
  • @mydogisbox - MathNet.NumericsMathNet.Numerics.FSharp 都是版本 3.19.0Newtonsoft.Json 是版本10.0.3 但即使我不安装它也会出现问题。 FuleSnabel 的回答表明问题是由于转移到FSharp.Core.3.1.2.5FSharp.Core 的旧版本。
  • @Soldalma 我添加了一个答案,向您展示了如何在不深入 fsproj 内部的情况下执行此操作,并且还扩展了 Paket。希望您再试一次,因为它也可以在命令行中使用,也可以在 VSCode 中使用。

标签: f# nuget packages


【解决方案1】:

MathNet.Numerics.FSharp 依赖于 FSharp.Core.3.1.2.5,它替换了您正在使用的 FSharp.Core 的当前版本。年纪大了3.1.2.5 功能少了很多。

这也发生在其他流行的F# 库中,例如FsCheck。我通常将引用更改为 FSharp.Core 的最新版本,因为它应该是向后兼容的。

为此,我卸载了F# 项目并将项目文件中的FSharp.Core 引用更新为:

<Reference Include="FSharp.Core">
  <Name>FSharp.Core</Name>
  <AssemblyName>FSharp.Core.dll</AssemblyName>
  <HintPath>$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>

然后我重新加载项目。

由于这是一个相当笨拙的过程,希望更有洞察力的用户会发布更好的解决方案。

【讨论】:

  • 笨拙与否。非常感谢。有没有教初学者如何处理项目文件的书/PDF/链接?
  • @Soldalma use paket ;-) fsprojects.github.io/Paket Paket 会为您检查所有这些内容,并允许您明确依赖关系。
  • @mydogisbox - 对我来说不是这样。我尝试了 Paket,不得不重新安装 VS Studio 2017 才能摆脱它。相同类型的问题,但更糟。也许是因为我不知道如何使用它。 Paket 发出的错误消息对我来说是无法理解的。对于对项目、构建等知之甚少的初学者,我找不到说明。此外,使用 Paket 一个必须处理三个文件,而 Nuget 只有一个。
  • @Soldalma 我最初设置它时也遇到了问题。理解它的工作绝对值得付出努力。
  • @Soldalma - 另外,使用 Paket 一个必须处理三个文件,而使用 Nuget 它只有一个。 一旦你了解了为什么 Paket 将概念分成三个文件,你' 会在另一个方向抱怨这个:“为什么 NuGet 将东西合并到一个文件中,而应该清楚地将它们分成不同的文件?” :-) 能够提交您的 paket.lock 文件并知道所有其他开发人员在运行 paket restore 时将获得完全相同相同版本的依赖项,这让您高枕无忧,例如。
【解决方案2】:

嗯,我认为 OP 的担忧是有道理的。我不鼓励手动编辑 fsproj 文件。而且 cmets 也非常有效,Paket 是一个很棒的工具,可以简化 VS 和 Code 中的依赖管理。因此,这是一个非常简单的两部分答案,其中 a) 您实际上可以使用 nugget 使您的解决方案正常工作,而无需手动编辑项目文件,b) 快速介绍如何在 VS 上使用 paket。

这个问题有时会发生一些包下载和旧的依赖关系会弄乱其他代码,这可能是由于依赖于最小可行版本的策略。你的问题有点类似于这个Q:Why can't I get suave to work

这是仅使用 nugget 的最简单解决方案:

  1. 使用 fsharp 控制台项目打开一个新的解决方案
  2. 此时您在 VS2017 中的 Fsharp.Core 将是 4.1:

  1. 现在通过 nugget 添加 Mathnet.Numerics.Fsharp:

现在,很不幸你被降级到 F# 3.1

  1. 这不好,所以也可以通过 nugget 获取 Fsharp.Core!

  1. 瞧,您无需编辑 fsproj 即可返回工作解决方案。基本上你所要做的就是添加 Fsharp.Core 包。您还可以更改属性中的 .NET Framework 选项,并使用 Fsharp 4.1 将其移至 .NET 4.7:

现在是关于 Paket 答案的第 2 部分(顺便说一句,Paket 插件刚刚更新,我进行了测试,它工作正常)。您基本上可以将其用作 nugget 的替代品或直接编辑文件。您实际上需要处理两个文件,解决方案根目录中的paket.dependencies 和项目根目录中的paket.referencesPaket.lock 将被生成。这是开始的两步过程。拿你刚刚在上面创建的项目,从 VS 的工具菜单中选择Paket Dependencies Manager,执行Initialize Paket,然后执行Convert From Nuget

有了这个,您可以继续使用 nuget 管理您的依赖项,或者如果您愿意,可以使用 paket。接下来我会将 Newtonsoft.JSON 添加到引用中。双击paket.dependencies 文件并添加以下行:nuget Newtonsoft.Json 10.0.3 restriction: &gt;= net452,您实际上只需要Newtonsoft.Json,但我们不想下载整个名为.NetCore 的互联网。还要将此行添加到paket.references(您可以在项目资源管理器中单击它):Newtonsoft.Json。和运行工具 |包|安装:

Paket.dependencies:

Paket.references:

然后运行 ​​Paket 安装:

您将安装 Newtonsoft.JSON。通常你不需要指定框架限制的版本,但是它有一些你可能不想要的预发布包,而且我假设你不需要 .netcore 依赖项。

您实际上可以右键单击并尝试从参考添加包菜单中安装此包,但您会遇到依赖错误。

【讨论】:

  • 非常感谢。高超。我仔细看了你答案的第一部分,当然一切都如你所说。但我对最后一句话有点困惑:“您也可以更改属性中的 .NET Framework 选项,并使用 Fsharp 4.1 将其移动到 .NET 4.7” 我打开项目属性并看到一个类似于您帖子中的页面.但是在我的屏幕和您发布的页面中,它都有“.NET Framework 4.5.2”并且您提到了“.NET 4.7”。请不要介意这是一个愚蠢的问题。我正在学习。
  • 在答案的第 2 部分,我知道 Paket 在很多方面都比已经很出色的 Nuget 更好。但是在遇到 Paket 问题后,我不得不重新安装 VS 三次,因为我不具备处理所面临问题的知识。我想尝试您的建议,但是如果有一种方法可以卸载 Paket,而无需卸载并重新安装 VS,以防万一事情无法按预期工作,那会更容易。那可能吗?我可以使用 Git/Bitbucket(这就是我使用的)来做到这一点吗?
  • 如果你不想,你不需要使用 paket。即这不是一个要求。 paket 只是一个 exe,您可以随时删除 .paket 文件夹。您也可以从 VS 的工具菜单中卸载 VS paket 插件。
  • re:.Net 框架,.Net 基类库有各种版本,4.6、4.7。在属性页面中,您可以选择要定位的版本。您还可以选择要定位的 F# Core。我相信您可以在 VS2017 中定位 4.6.x,并且您需要安装 4.7 定位包才能使用它。这些都是向后兼容的版本,但包括重大修复和新方法,例如 4.6 中出现的 DateTime 中的 unix 时间。
猜你喜欢
  • 2018-02-08
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
相关资源
最近更新 更多