F# 调用“argv”中为“[<;EntryPoint>;]”定义的特定函数,或动态命名要调用的函数
是否可以以某种方式定义调用的函数名和/或在F#中动态打开的模块名 谷歌搜索互联网似乎表明,只有当“名字”是某一类型的成员时,才可能使用内省 我问这个问题的原因是因为我对的F# 调用“argv”中为“[<;EntryPoint>;]”定义的特定函数,或动态命名要调用的函数,f#,entry-point,F#,Entry Point,是否可以以某种方式定义调用的函数名和/或在F#中动态打开的模块名 谷歌搜索互联网似乎表明,只有当“名字”是某一类型的成员时,才可能使用内省 我问这个问题的原因是因为我对的[]的解决方案开始看起来很简单,而且肯定不会干涸 我所有的“解谜”函数都是在特定于日期的模块中定义的,并且具有相同的签名String->Unit->int64,也就是说,它们以一个文件名作为输入(出于测试的目的,因为大多数(如果不是全部的话)谜题都有测试向量)和单元(这样它们在模式匹配时就不会全部执行) 打开AoC2020.Ut
[]
的解决方案开始看起来很简单,而且肯定不会干涸
我所有的“解谜”函数都是在特定于日期的模块中定义的,并且具有相同的签名String->Unit->int64
,也就是说,它们以一个文件名作为输入(出于测试的目的,因为大多数(如果不是全部的话)谜题都有测试向量)和单元(这样它们在模式匹配时就不会全部执行)
打开AoC2020.Utils
打开AOC20.Day1
打开AOC20.Day2
开放AOC20.Day3
开放AOC20.Day4
开放AOC20.Day5
打开AOC20.Day6
开放AOC20.Day7
开放AOC20.Day8
开放AOC20.Day9
[]
让主argv=
let day=argv |>getProblem
比赛日
|“1”->第1天“1”()
|“1b”->第1天第2部分“1”()
|“2”->第2天“2”()
|“2b”->第2天第2部分“2”()
|“3”->第3天“3”()
|“3b”->第3天第2部分“3”()
|“4”->第4天“4”()
|“4b”->第4天第2部分“4”()
|“5”->第5天“5”()
|“5b”->第5天第2部分“5”()
|“6”->第6天“6”()
|“6b”->第6天第2部分“6”()
|“7”->第7天“7”()
|“7b”->第7天第2部分“7”()
|“8”->第8天“8”()
|“8b”->第8天第2部分“8”()
|_uu->1L
|>printfn“%d”
0
…还是我做了一些完全错误的事情,并且有更好的方法来实现同样的事情?更一般地说,我可能不会为代码的出现而费心创建一个复杂的启动器-对于我做的几个难题,我只是将每个拼图的代码保存在一个脚本文件中,然后通过选择所有拼图并在F#Interactive中运行来运行它,而不是使用命令行界面 然而,如果您更喜欢命令行界面,那么您应该能够使用反射来做您想要做的事情。每个F#模块被编译成一个类,您可以使用
Assembly.getExecutionGassembly().GetTypes()
获取所有加载类的列表,找到所需的类并调用已知的方法,例如run
例如:
module Day1 =
let run () = printfn "day 1"
module Day2 =
let run () = printfn "day 2"
module Day2b =
let run () = printfn "day 2b"
采用模块名称并运行其run
函数的(非常基本)函数如下所示:
open System.Reflection
let run name =
let typ =
Assembly.GetExecutingAssembly().GetTypes()
|> Seq.find (fun t -> t.Name = name)
typ.GetMethod("run").Invoke(null, [||]) |> ignore
要测试这一点:
run "Day1"
run "Day2"
run "Day2b"
虽然我同意,一般来说,我不会费心创建一个复杂的启动器,但我将代码的出现作为一个平台来学习如何正确使用F#和.NET。。。因此,对我来说,“复杂的发射器”是一个一般性的问题,与Django的管理命令非常类似。谢谢,我很确定我能理解这里发生了什么,即使是C#:)@Kimvais的绝对0背景也完全有道理!(我只是想添加一个免责声明,因为一些来到F#的人倾向于以过于复杂的方式做事:-)反射肯定是.NET中更神秘的领域之一。。。
run "Day1"
run "Day2"
run "Day2b"