首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >匹配可变对象(字符串)的F#

匹配可变对象(字符串)的F#
EN

Stack Overflow用户
提问于 2010-09-16 11:27:30
回答 3查看 214关注 0票数 0

以下是到目前为止的完整代码:

代码语言:javascript
复制
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以外的任何内容...我不确定我在哪里犯了错。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-16 11:53:47

两件事。

  1. 在F#中,可以隐藏绑定。特别是,在您的match中,当您在模式中使用game1game2game3时,您实际上是在使用这些名称声明新的绑定。因此,第一个模式将始终匹配,并且只会在计算右侧之前将您尝试与之匹配的任何值分配给新的绑定game1

解决此问题的一种方法是使用[<Literal>]属性声明gameN绑定(但请注意,它们还必须以大写字母开头才能作为常量使用):

[<Literal>] let Game1 = "Assassin's Creed"

现在,您可以在模式匹配中使用Game1,它将按照您的预期工作。

  • 您可能知道这一点,但您实际上并没有在任何地方更新gameprint绑定,因此在整个程序中,它将被设置为相同的值,并且它不是可变的。
票数 4
EN

Stack Overflow用户

发布于 2010-09-16 11:40:28

有关说明,请参阅F# matching with two values

在与几个非文本值进行比较时,我只使用if-then-else

代码语言:javascript
复制
if gameprint = game1 then ...
elif gameprint = game2 then ...
...
票数 3
EN

Stack Overflow用户

发布于 2010-09-16 14:50:28

也许更像这样的东西会让它更具可扩展性(如果你在运行时填充游戏列表)……抱歉,代码有点匆忙,我正准备去上班:

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3723488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档