modularml / mojo

The Mojo Programming Language
https://docs.modular.com/mojo
Other
22.41k stars 2.55k forks source link

[BUG]: dict for e in dict problem (key value) #1843

Open stefanuytterhoeven opened 4 months ago

stefanuytterhoeven commented 4 months ago

Bug description

test program:

start source

from collections.dict import Dict, KeyElement

@value
struct StringKey(KeyElement):
    var s: String

    fn __init__(inout self, owned s: String):
        self.s = s ^

    fn __init__(inout self, s: StringLiteral):
        self.s = String(s)

    fn __hash__(self) -> Int:
        var ptr = self.s._buffer.data.value
        return hash(DTypePointer[DType.int8](ptr), len(self.s))

    fn __eq__(self, other: Self) -> Bool:
        return self.s == other.s
fn main() raises:
    var s=Dict[StringKey,String]()
    s["a"]="test"
    s["b"]="test2"
    print(s["a"])
    if "a" in s:
        print("a exists in s")
    else:
        print("s does not exist in s")
    if "c" in s:
        print("c exists in s")
    else:
        print("s does not exist in s")

    for e in s.items():
        print(e[].key.s,e[].value)

end source

Problem: for e in s.items() statements: according to the documentation it has to be

    for e in s.items():
        print(e[].key,e[].value)

but this gives errors: error: no matching function in call to 'print': note: candidate not viable: expected at most 0 positional arguments, got 2 note: candidate not viable: expected at most 1 positional arguments, got 2 note: candidate not viable: expected at most 1 positional arguments, got 2 ....

when playing with it,

 for e in s.items():
        print(e[].key.s,e[].value) 

works. e[].key cannot be used, but e[].key.s can be used. I guess the "s" is from the StringKey struct

This is not how it's documented.

Steps to reproduce

System information

- What OS did you do install Mojo on ?
 ubuntu wsl
- Provide version information for Mojo by pasting the output of `mojo -v` 
mojo 24.1.0 (55ec12d6)
- Provide Modular CLI version by pasting the output of `modular -v`
modular 0.5.1 (1b608e3d)

UPDATE: since release mojo 24.1.0 , no need to create the stringkey struct ? apparently you can create a dict by var newdict=Dict[String,String]() newdict["testkey1]="testvalue1"

This WORKS. But, the documentation about DICT isnt updated yet.

soraros commented 4 months ago

Do you mind fixing the formatting of your repro (by wrapping the code in triple backquote)?

stefanuytterhoeven commented 4 months ago

Do you mind fixing the formatting of your repro (by wrapping the code in triple backquote)?

done :)

soraros commented 4 months ago

You don't need to wrap your String key in a StringKey struct any more in 24.1. The following works:

from collections import Dict

fn main():
  var d = Dict[String, Int]()
  d["a"] = 1

  for t in d.items():
    print(t[].key, t[].value)