为什么添加一些包会破坏我的代码?
Why adding some packages breaks my code?
我注意到添加包有时会破坏我的代码。 Seq.replicate
和 List.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.replicateand
List.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)安装来避免这个问题?
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>
然后我重新加载项目。
因为这是一个相当笨拙的过程,希望更有洞察力的用户会 post 更好的解决方案。
嗯,我认为 OP 的担忧在一定程度上是有道理的。我不鼓励 hand-editing fsproj 文件。而且评论也非常有效,Paket 是一个很棒的工具,可以简化 VS 和代码中的依赖项管理。因此,这是一个非常简单的两部分答案,其中 a) 您实际上可以使用 nugget 而无需 hand-editing 项目文件来使您的解决方案正常工作,以及 b) 快速介绍如何在 VS 上使用 paket。
这个问题时不时会出现一些包下载和旧的依赖关系搞乱其他代码,这可能是由于依赖最小可行版本的策略。您的问题与此问题有些相似:.
这是仅使用块的最简单的解决方案:
- 使用 fsharp 控制台项目打开一个新解决方案
- 此时你在 VS2017 中的 Fsharp.Core 将是 4.1:
- 现在通过块添加 Mathnet.Numerics.Fsharp:
现在,很遗憾您已降级到 F# 3.1
- 这不行,所以也只能通过 nugget 获取 Fsharp.Core!
- 瞧,您回到了工作解决方案,无需编辑 fsproj。基本上你所要做的就是添加 Fsharp.Core 包。您还可以更改属性中的 .NET Framework 选项并将其移动到带有 Fsharp 4.1 的 .NET 4.7:
现在是 Paket 答案的第 2 部分(顺便说一句,Paket 插件刚刚更新,我测试过它工作正常)。您基本上可以将其用作 nugget 的替代品或直接编辑文件。您实际上需要使用两个文件,解决方案根目录中的 paket.dependencies
和项目根目录中的 paket.references
。 Paket.lock
将生成。这是开始的 two-step 过程。从 VS select Paket Dependencies Manager
的“工具”菜单中获取您刚刚创建的项目,执行 Initialize Paket
,然后执行 Convert From Nuget
:
有了这个,您可以继续使用 nuget 管理您的依赖项,或者如果您愿意,可以使用 paket。接下来我将在参考文献中添加 Newtonsoft.JSON。 Double-click 在 paket.dependencies
文件上并添加以下行: nuget Newtonsoft.Json 10.0.3 restriction: >= net452
,您实际上只需要 Newtonsoft.Json 在那里,但我们不想下载整个名为 .NetCore 的互联网.还要将此行添加到 paket.references
(您可以在项目浏览器中单击它):Newtonsoft.Json
。还有 运行 工具 |包裹|安装:
Paket.dependencies:
Paket.references:
和运行 数据包安装:
您将安装 Newtonsoft.JSON。通常你不需要指定框架限制的版本,但是它有一些你可能不需要的 pre-release 包,而且我假设你不需要 .netcore 依赖项。
您实际上可以右键单击并尝试从参考添加包菜单中安装此包,但您会遇到依赖性错误。
我注意到添加包有时会破坏我的代码。 Seq.replicate
和 List.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.replicateand
List.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)安装来避免这个问题?
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>
然后我重新加载项目。
因为这是一个相当笨拙的过程,希望更有洞察力的用户会 post 更好的解决方案。
嗯,我认为 OP 的担忧在一定程度上是有道理的。我不鼓励 hand-editing fsproj 文件。而且评论也非常有效,Paket 是一个很棒的工具,可以简化 VS 和代码中的依赖项管理。因此,这是一个非常简单的两部分答案,其中 a) 您实际上可以使用 nugget 而无需 hand-editing 项目文件来使您的解决方案正常工作,以及 b) 快速介绍如何在 VS 上使用 paket。
这个问题时不时会出现一些包下载和旧的依赖关系搞乱其他代码,这可能是由于依赖最小可行版本的策略。您的问题与此问题有些相似:
这是仅使用块的最简单的解决方案:
- 使用 fsharp 控制台项目打开一个新解决方案
- 此时你在 VS2017 中的 Fsharp.Core 将是 4.1:
- 现在通过块添加 Mathnet.Numerics.Fsharp:
现在,很遗憾您已降级到 F# 3.1
- 这不行,所以也只能通过 nugget 获取 Fsharp.Core!
- 瞧,您回到了工作解决方案,无需编辑 fsproj。基本上你所要做的就是添加 Fsharp.Core 包。您还可以更改属性中的 .NET Framework 选项并将其移动到带有 Fsharp 4.1 的 .NET 4.7:
现在是 Paket 答案的第 2 部分(顺便说一句,Paket 插件刚刚更新,我测试过它工作正常)。您基本上可以将其用作 nugget 的替代品或直接编辑文件。您实际上需要使用两个文件,解决方案根目录中的 paket.dependencies
和项目根目录中的 paket.references
。 Paket.lock
将生成。这是开始的 two-step 过程。从 VS select Paket Dependencies Manager
的“工具”菜单中获取您刚刚创建的项目,执行 Initialize Paket
,然后执行 Convert From Nuget
:
有了这个,您可以继续使用 nuget 管理您的依赖项,或者如果您愿意,可以使用 paket。接下来我将在参考文献中添加 Newtonsoft.JSON。 Double-click 在 paket.dependencies
文件上并添加以下行: nuget Newtonsoft.Json 10.0.3 restriction: >= net452
,您实际上只需要 Newtonsoft.Json 在那里,但我们不想下载整个名为 .NetCore 的互联网.还要将此行添加到 paket.references
(您可以在项目浏览器中单击它):Newtonsoft.Json
。还有 运行 工具 |包裹|安装:
Paket.dependencies:
Paket.references:
和运行 数据包安装:
您将安装 Newtonsoft.JSON。通常你不需要指定框架限制的版本,但是它有一些你可能不需要的 pre-release 包,而且我假设你不需要 .netcore 依赖项。
您实际上可以右键单击并尝试从参考添加包菜单中安装此包,但您会遇到依赖性错误。