0

これまでの完全なコードは次のとおりです。

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 以外のものとは一致しません...よくわかりません間違えたところ。

4

3 に答える 3

4

2つのこと。

  1. F# では、バインドをシャドーイングできます。特に、 内で、、およびをパターンでmatch使用する場合、実際にはこれらの名前で新しいバインディングを宣言しています。したがって、最初のパターンは常に一致し、右辺を評価する前に、一致させようとしている値を新しいバインディングに割り当てるだけです。game1game2game3game1

    これを回避する 1 つの方法は、[<Literal>]属性を使用して gameN バインディングを宣言することです (ただし、定数として機能させるには大文字で始める必要があることに注意してください)。

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

    これで、パターン マッチで使用できるようGame1になり、期待どおりに動作します。

  2. これに気付いているかもしれませんが、実際にはgameprintどこでもバインディングを更新しているわけではないため、プログラム全体で同じ値に設定され、可変であっても意味がありません。

于 2010-09-16T03:53:46.747 に答える
3

説明については、 F# の 2 つの値のマッチングを参照してください。

いくつかの非リテラル値と比較するときは、if-then-else を使用します

if gameprint = game1 then ...
elif gameprint = game2 then ...
...
于 2010-09-16T03:40:28.177 に答える
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)
于 2010-09-16T06:50:27.567 に答える