以下是目前的完整代码:
module clean
#light
open System
open System.IO
let pause() = Console.ReadLine()
let drive = System.IO.Directory.GetDirectoryRoot(System.IO.Directory.GetCurrentDirectory())
printfn "You're using the %s drive.\n\n" drive
let game1 = "Assassin's Creed"
let game2 = "Crysis"
let game3 = "Mass Effect"
let local1 = "\%APPDATA\%\\Ubisoft\\Assassin's Creed\\Saved Games\\"
let local2 = "\%USERPROFILE\%\\Documents\\My Games\\Crysis\\SaveGames\\"
let local3 = "\%USERPROFILE\%\\Documents\\BioWare\\Mass Effect\\Save\\"
let roam1 = drive + "Saves\\Abraxas\\" + game1 + "\\"
let roam2 = drive + "Saves\\Abraxas\\" + game2 + "\\"
let roam3 = drive + "Saves\\Abraxas\\" + game3 + "\\"
let rec getGame() =
printfn "Which Game?\n\n 1.%s\n 2.%s\n 3.%s\n\n" game1 game2 game3
match Int32.TryParse(stdin.ReadLine()) with
| true,1 -> game1
| true,2 -> game2
| true,3 -> game3
| _ ->
printfn "You did not enter a valid choice."
let _ = pause()
Console.Clear()
getGame()
let mutable gameprint = getGame()
printf "You have chosen %s\n\n" gameprint
let roaming =
match gameprint with
| game1 -> roam1
| game2 -> roam2
| game3 -> roam3
| _ -> "test"
printf "Roaming set to %s\n\n" roaming
let local =
match gameprint with
| game1 -> local1
| game2 -> local2
| game3 -> local3
| _ -> "test"
printf "Local set to %s\n\n" local
printf "Check gameprint %s" gameprint
在设置漫游和本地对象的部分中,它告诉我它将永远不会与“game1”以外的任何内容匹配。
我在匹配本地和漫游对象之前和之后检查了'printf'...游戏打印在两个printf命令中都正确显示,但是与game1以外的任何内容都不匹配......我我不确定我犯了哪个错误。
答案 0 :(得分:4)
两件事。
在F#中,绑定可以被遮蔽。特别是,在match
内,当您在模式中使用game1
,game2
和game3
时,您实际上是在声明新绑定名。因此,第一个模式将始终匹配,并且只会在评估右侧之前将您尝试匹配的任何值分配给新绑定game1
。
解决此问题的一种方法是使用[<Literal>]
属性声明gameN绑定(但请注意,它们也必须以大写字母开头才能作为常量使用):
[<Literal>]
let Game1 = "Assassin's Creed"
现在,您可以在模式匹配中使用Game1
,它可以按预期运行。
您可能已经意识到这一点,但实际上您并没有在任何地方更新gameprint
绑定,因此在整个程序中它将被设置为相同的值,并且没有任何意义是可变的。
答案 1 :(得分:3)
请参阅F# matching with two values以获取解释。
当与一些非文字值进行比较时,我只使用if-then-else
if gameprint = game1 then ...
elif gameprint = game2 then ...
...
答案 2 :(得分:1)
也许更像这样的东西可以让你更具可扩展性(如果你在运行时填充游戏列表)...对不起代码有点匆忙我正在努力为工作做准备:
open System
type Game = {Title:string; local:string; roam:string}
let game1 = {
Title= "Assassin's Creed";
local = "\%APPDATA\%\\Ubisoft\\Assassin's Creed\\Saved Games\\";
roam = "Saves\\Abraxas\\\Assassin's Creed\\"
}
let game2 = {
Title= "Crysis";
local = "\%USERPROFILE\%\\Documents\\My Games\\Crysis\\SaveGames\\";
roam = "Saves\\Abraxas\\\Crysis\\"
}
let games = [game1; game2]
let printGamelListItem i g = printfn "%i: %s" i g.Title
let printChoice() =
printfn "Which Game?\n"
games |> List.fold (fun acc g ->
printGamelListItem acc g
acc+1) 1
|> ignore
let rec getGame() =
printChoice()
match Int32.TryParse(Console.ReadLine()) with
|true, x when x <= games.Length -> games.[x-1]
| _ ->
printfn "You did not enter a valid choice."
let _ = Console.ReadLine()
Console.Clear()
getGame()
let selection = getGame()
printfn "Roaming set to: %s" (selection.roam)
printfn "Local set to: %s" (selection.local)