Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

rust - Generic function that returns different types based on the value of an argument

I have a struct which holds registers. I want my read_register function to return a u8 for Register::V0 and Register::V1 but a u16 for Register::V2 and Register::V3. I'm not sure how to make the function generic over the return type. I'm getting the error match arms have incompatible types which does make sense because the types are different.

struct Registers {
    v0: u8,
    v1: u8,
    v2: u16,
    v3: u16,
}

enum Register {
    V0,
    V1,
    V2,
    V3,
}

impl Registers {
    fn read_register<T>(&self, register: Register) -> T {
        match register {
            Register::V0 => self.v0,
            Register::V1 => self.v1,
            Register::V2 => self.v2,
            Register::V3 => self.v3,
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't.

Sorry, but there's just no way of doing this in Rust. You'd need dependent types, which Rust doesn't have. You could perhaps return an instance of an enum that just contains two variants (one for each type). Or you could accept one callback for each "path" and let the caller decide how to resolve the problem.

fn read_register<FnU8, FnU16, R>(
    &self,
    register: Register,
    with_u8: FnU8,
    with_u16: FnU16,
) -> R
where
    FnU8: FnOnce(u8) -> R,
    FnU16: FnOnce(u16) -> R,
{
    match register {
        Register::V0 => with_u8(self.v0),
        Register::V1 => with_u8(self.v1),
        Register::V2 => with_u16(self.v2),
        Register::V3 => with_u16(self.v3),
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...