Say I want to have a struct called Tile that will have a suit (let it be a string for simplicity’s sake) and a number. This number can only exist in the range of 1-9.

In Nim, for example, you can do something like this:

type 
  Tile = object
    suit: string
    num: range[1..10]

var t = Tile(suit: "test", num: 9)
echo t.num # 9
t.num += 2 # OverflowDefect

How can I do such a thing in Rust? I can only think of one way: not allowing the number to be out of range in the “new” constructor and then adding auxiliary methods (add, sub, etc.) that do bounds checking. This solution seems too complex, though. There might be a way to do this using various range traits, but I can’t seem to figure out how.

  • dillekant@slrpnk.net
    link
    fedilink
    English
    arrow-up
    3
    ·
    2 years ago

    You’ll notice that new is not a keyword or any special rust thing. It’s actually a software design pattern called a smart constructor, and validation is part of the intent. Pattern wise putting this into a smart constructor and encapsulating changes to this value is, I believe, idiomatic.

    IIUC rust does not have a type system where you can give numeric bounds. Creating one would likely mean you’d need to define all the maths, which is likely not worth it.

      • dillekant@slrpnk.net
        link
        fedilink
        English
        arrow-up
        1
        ·
        edit-2
        2 years ago

        I was actually vaguely thinking that for playing cards, there’s no actual way to do maths on it (like you can’t add an Ace to a Jack, or a Joker to a Queen). Are Aces high? Is the 2 worth 2 points or something else? So maybe OP is better off just defining the ranks manually (A, 2, 3 … J, Q K) and then separate out any points calculations. In that sense, OP might actually want the game rules encoded into the type system.

        EDIT: Also, nice, I remember reading that story.

  • Aethersong@lemmy.world
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 years ago

    You might be able to make num a newtype and make a custom implementation of the Add trait for it that checks that it is in bounds

  • bbaldino@lemmy.ml
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 years ago

    As far as I know, these are referred to as refinement/range/pattern types. There’s some official discussion here (nothing in the language yet). There’s a library called flux though that implements a form of it