简体   繁体   中英

How to write a recursive generic type in Rust?

I want to define a HashMap with a key type of String and the value type is itself.

I tried to write something like:

HashMap<String, HashMap<String, ...>>

I found this requires recursion and I don't know how to write recursion in a type.

After reading Recursive generic types , I tried:

type HashToHash = HashMap<String, HashToHash>

However I got error:

error[E0391]: cycle detected when processing `HashToHash`
 --> src/lib.rs:3:35
  |
3 | type HashToHash = HashMap<String, HashToHash>;
  |                                   ^^^^^^^^^^
  |
  = note: ...which again requires processing `HashToHash`, completing the cycle

Is there a way to define this kind of type in Rust?

The compiler is trying to tell you that you are about to define an infinite type. The reason for your mistake is that generics in C# and Java are ∀-polymorphic, ie one implementation exists for all parameters. Rust is λ-polymorphic, ie for each parameter an implementation is created (and optimized). This is what is usually called a template and you might know it from C++. If Rust developers of the early days would have had more experience, a lot of concepts in Rust would be known under different names. Generics is just one of it.

The only way to resort from the infinite loop is to use some sort of pointer to the type you define on your RHS.

Honstly, I found this question because I wanted to know if Rust can predeclare a template and use pointers to it without knowing the definition. As I did not find any documentation on the topic, the answer is likely no.

If you really need this, you can, in any λ-polymorphic language, resort to an untyped pointer to break the recursion. Doing so, you should wrap all data access behind an API.

From comments:

use std::collections::HashMap;

struct HashToHash(HashMap<String, HashToHash>);

fn main() {
    let mut h = HashToHash(HashMap::new());
    h.0.insert("gloink".to_owned(), HashToHash(HashMap::new()));
}

Playground link

Reference to original comments: 1 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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