简体   繁体   English

使用Array.Count并匹配大小写F#

[英]Using Array.Count and match cases F#

I am not sure yet what the problem is, I am trying to go through a ResizeArray and matching the item with the data type, and depending on this, take away the value in a specific field (iSpace) from thespace(which is how much space the inventory has), before returning the final value. 我还不确定是什么问题,我正在尝试通过ResizeArray并将该项目与数据类型进行匹配,并据此从空间中删除特定字段(iSpace)中的值(即返回最终值之前)。

A snippet of my code : 我的代码片段:

let spaceleft =
    let mutable count = 0 //used to store the index to get item from array
    let mutable thespace = 60 //the space left in the inventory
    printf "Count: %i \n" inventory.Count //creates an error
    while count < inventory.Count do 
        let item = inventory.[count]
        match item with
            |Weapon weapon ->

                thespace <- (thespace - weapon.iSpace)

            |Bomb bomb ->

                thespace <-(thespace - bomb.iSpace)

            |Potion pot ->

                thespace <- (thespace - pot.iSpace)

            |Armour arm ->

                thespace <- (thespace - arm.iSpace)


        count <- count+1
    thespace

I get an error about Int32, that has to do with the 我收到有关Int32的错误,这与

printf "Count: %i \n" inventory.Count

line 线

Another problem is that thespace doesn't seem to change, and always returns as 60, although I have checked and inventory is not empty, it always has at least two items, 1 weapon and 1 armour, so thespace should atleast decrease yet it never does. 另一个问题是,空间似乎没有变化,尽管我检查并且库存不为空,但空间总是返回60,它总是至少有两项,一件武器和一件装甲,因此该空间应至少减少,但永远不要减少做。 Other snippets that may help: 其他可能有帮助的摘要:

let inventory = ResizeArray[]

let initialise  = 
    let mutable listr = roominit
    let mutable curroom = 3
    let mutable dead = false
    inventory.Add(Weapon weap1)
    inventory.Add(Armour a1)
    let spacetogo = spaceleft //returns 60, although it should not

Also, apart from the iniitialise function, other functions seem not to be able to add items to the inventory properly, eg: 另外,除了初始化功能外,其他功能似乎也无法将物品正确添加到库存中,例如:

let ok, input = Int32.TryParse(Console.ReadLine())

match ok with
    |false ->
        printf "The weapon was left here \n"
        complete <- false
    |true ->
        if input = 1 && spaceleft>= a.iSpace then
            inventory.Add(Weapon a)
            printf "\n %s added to the inventory \n" a.name
            complete <- true
        else
            printf "\n The weapon was left here \n"
            complete <- false
complete

You have spaceLeft as a constant value. 您将spaceLeft作为常数。 To make it a function you need to add unit () as a parameter. 要使其具有功能,您需要添加unit ()作为参数。 Here's that change including a modification to make it much simpler (I've included my dummy types): 这是该更改,其中包括使它更简单的修改(我包括了我的虚拟类型):

type X = { iSpace : int }
type Item = Weapon of X | Bomb of X | Potion of X | Armour of X
let inventory = ResizeArray [ Weapon {iSpace = 2}; Bomb {iSpace = 3} ]

let spaceleft () =
    let mutable thespace = 60 //the space left in the inventory
    printf "Count: %i \n" inventory.Count
    for item in inventory do
        let itemSpace =
            match item with
            | Weapon w -> w.iSpace
            | Bomb b -> b.iSpace
            | Potion p -> p.iSpace
            | Armour a -> a.iSpace
        thespace <- thespace - itemSpace
    thespace

spaceleft () // 55

The above code is quite imperative. 上面的代码非常必要。 If you want to make it more functional (and simpler still) you can use Seq.sumBy : 如果要使其功能更强大(并且更简单),可以使用Seq.sumBy

let spaceleft_functional () =
    printf "Count: %i \n" inventory.Count
    let spaceUsed =
        inventory
        |> Seq.sumBy (function
            | Weapon w -> w.iSpace
            | Bomb b -> b.iSpace
            | Potion p -> p.iSpace
            | Armour a -> a.iSpace)
    60 - spaceUsed

Just adding to the accepted answer: you can also match against record labels, as long as your inner types are records. 只需添加已接受的答案即可:只要您的内部类型是记录,您还可以与记录标签匹配。 Combine with an intrinsic type extension on the outer DU: 与外部DU上的固有类型扩展结合使用:

type X = { iSpace : int }
type Y = { iSpace : int }
type Item = Weapon of X | Bomb of Y | Potion of X | Armour of X
let inventory = ResizeArray [ Weapon {iSpace = 2}; Bomb {iSpace = 3} ]

let itemSpace = function
| Weapon { iSpace = s } | Bomb { iSpace = s }
| Potion { iSpace = s } | Armour { iSpace = s } -> s
type Item with static member (+) (a, b) = a + itemSpace b

60 - (Seq.fold (+) 0 inventory)
// val it : int = 55

Otherwise, you could resort to member constraint invocation expressions. 否则,您可以诉诸成员约束调用表达式。

let inline space (x : ^t) = (^t : (member iSpace : int) (x))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM