使用f#模拟linux touch命令,需要帮助实现
我正在尝试编写一个f#程序,它模仿linux中的touch命令,它检查文件路径是否存在,是否更新了时间戳,是否不存在,是否创建了文件。如何正确地实现这一点 我尝试过使用.net函数,我认为它基本上实现了我需要的功能。我正在使用file.exists、file.create和file.setlastaccesstime //了解更多关于F#at的信息使用f#模拟linux touch命令,需要帮助实现,f#,touch,f#-interactive,F#,Touch,F# Interactive,我正在尝试编写一个f#程序,它模仿linux中的touch命令,它检查文件路径是否存在,是否更新了时间戳,是否不存在,是否创建了文件。如何正确地实现这一点 我尝试过使用.net函数,我认为它基本上实现了我需要的功能。我正在使用file.exists、file.create和file.setlastaccesstime //了解更多关于F#at的信息 opensystem.IO 类型Filepath=string 让触摸= 让我们检查存在的文件路径= 如果File.Exists文件路径 然后是Re
opensystem.IO
类型Filepath=string
让触摸=
让我们检查存在的文件路径=
如果File.Exists文件路径
然后是Result.Ok(filePath:filePath)
else结果。错误“文件不存在”
let path=Console.ReadLine()
让我们更新=
path=Console.ReadLine()
如果文件.Exists(路径)
创建(路径)
else文件.SetLastAccessTime(路径,DateTime.Now)
[]
让主argv=
printfn“windows触摸命令”
->触摸
->更新()
0//返回整数退出代码```
您的代码有几个问题。我会一个接一个地看一遍
首先,问题中代码的缩进完全搞乱了。如果这是代码的直接复制和粘贴,我们需要做的第一件事就是修复缩进:在F#中,缩进是重要的,并确定代码块。(如果您的问题的缩进被弄乱了,因为您在堆栈溢出问题编辑器中篡改缩进,并且实际代码缩进是好的,那么请考虑这是关于F压痕如何工作的复习)。
在F#中,这两个代码块的作用不同:
if value = 5 then
printfn "Five"
printfn "Value: %d" value
这将始终打印“Value:3”或“Value:27”或其他内容,如果值正好为5,也将打印单词“Five”。但下一个代码块还有其他功能:
if value = 5 then
printfn "Five"
printfn "Value: %d" value
这要么不打印任何内容,要么在下一行打印单词“5”,后跟“Value:5”。这是因为第二个printfn
函数调用与第一个函数调用在同一级别缩进,这意味着它是if
块的一部分
另外,let
语句后面需要跟在同一行的值后面,或者跟在缩进块后面:
let value = 5
let otherValue =
if value < 5 then
5
else
3
现在你可以像这样调用这个函数:
let value = 5
let otherValue = calculateValue value
// Now otherValue is equal to 3
这给我们带来了代码的第二个问题,即您显然打算将touch
和update
作为函数,但没有给它们提供参数。这意味着它们是只执行一次的值。您需要将let touch=
转换为let touch()=
以使touch
成为一个函数而不是一个值,对于update
也是如此
您遇到的另一个问题更多的是设计问题:您的update
函数正在做两件事。它从控制台读取一个值,并根据该值采取行动。更好的设计是让每个函数只做一件事:让您的更新
函数将路径
作为参数,然后在其他地方,您可以让代码从控制台读取路径
,并调用更新路径
。这使得编写测试update
函数的单元测试变得更加容易,因为您不必想办法将单元测试连接到stdin,只需让测试调用update
函数即可
古兰在评论中指出的另一个问题(谢谢!)是,update
函数的逻辑是反向的。您写了“如果文件存在,创建文件,否则设置上次访问时间”。应该是相反的。我在这个答案的第一个版本中遗漏了这一点,因此我更新了下面的固定代码,以更正更新中if…then…else
块的顺序
我看到的另一个问题是:你的touch
功能(目前它是一个值,但你显然有意让它成为一个功能)应该做什么?let touch=
块中唯一的内容是其他函数定义;touch
代码块从未实际调用它定义的函数。这意味着它是无用的:通过将这些函数定义放在touch
代码块内,您可以对touch
代码块外的任何代码隐藏它们,但是touch
代码块从不调用它们。在模块顶层定义的函数对于任何可以访问该模块的代码都是可见的。在代码块内定义的函数(和变量)仅在该代码块的范围内可见。这对于封装外部世界看不到的内容非常有用,例如在以下示例中:
let counter() =
let mutable value = 0
let update() =
value <- value + 1
value
update
这将打印“A1:1”、“A2:2”、“B1:1”,然后打印“B2:2”。现在作为练习,如果我在上面的代码中将let counter()=
替换为let counter=
,会发生什么?(我还必须将let a=counter()
更改为let a=counter
,对于let b=…
,也是如此)。试着猜测会发生什么,然后试着去做,看看你是否是对的。(提示:与函数不同,值只执行一次)
还有最后一件事:main
函数中的箭头不正确。这不是->
操作符的作用。如果需要在一行中调用多个函数,只需逐个编写函数调用
好的,这就是我现在所能做的,帮助您解决代码问题的全部工作。还有更多的问题(例如,最好从argv
获取路径,而不是从Console.ReadLine()
)获取路径),但这些问题可以等到您有了更多的F#经验后再解决。这是您的代码,以及我到目前为止提到的修复程序。哦,还有一个解决办法:我正在删除let touch=
行,因为我无法告诉您打算在touch
函数中添加什么。下面是您的代码,虽然有些修复,但仍需要更多修复:
open System.IO
type Filepath = string
// NOTE: This function is unused. Why do you have it?
let checkExists filePath =
if File.Exists filePath
then Result.Ok (filePath:Filepath)
else Result.Error "File does not exist"
let update path =
// Note: the "then" and "else" blocks are swapped from your original code
if File.Exists(path)
then File.SetLastAccessTime(path, DateTime.Now)
else File.Create(path)
[<EntryPoint>]
let main argv =
printfn "Touch command for windows"
let path = Console.ReadLine()
update path
0 // return an integer exit code
opensystem.IO
类型文件
let counter() =
let mutable value = 0
let update() =
value <- value + 1
value
update
let a = counter()
let b = counter()
let a1 = a()
let b1 = b()
let a2 = a()
let b2 = b()
printfn "A1: %d" a1
printfn "A2: %d" a2
printfn "B1: %d" b1
printfn "B2: %d" b2
open System.IO
type Filepath = string
// NOTE: This function is unused. Why do you have it?
let checkExists filePath =
if File.Exists filePath
then Result.Ok (filePath:Filepath)
else Result.Error "File does not exist"
let update path =
// Note: the "then" and "else" blocks are swapped from your original code
if File.Exists(path)
then File.SetLastAccessTime(path, DateTime.Now)
else File.Create(path)
[<EntryPoint>]
let main argv =
printfn "Touch command for windows"
let path = Console.ReadLine()
update path
0 // return an integer exit code