用于Rust中fn参数的协方差是什么?

问题描述 投票:3回答:1

今天,我了解到,锈仅在其返回类型为协变时不支持fn参数的协方差。 (see rust doc

为什么我了解到锈的事实?因为我试图实现一个非常简单的游戏,在其中我将逻辑,事件处理和绘图分离为三个不同的功能,但所有功能都在同一玩家矢量上进行。

如果不可能的话,与C#版本相比,生锈的等效值是多少?

在C#中,这非常简单Fiddle您可以定义类X必须实现的接口Y,并定义相应的委托,该委托需要该接口Y的IEnumerable作为参数。现在,您可以在仅需要接口Y的不同方法之间共享X的列表。]

using System;
using System.Collections.Generic;


public interface Actionable{
    void Do();
}

public interface Drawable{
    void Draw();
}

public class Player: Drawable, Actionable{

    public void Do(){
        Console.WriteLine("Action");
    }

    public void Draw(){
        Console.WriteLine("Draw");
    }
}

public class Program
{
    public delegate void DrawHandler(IEnumerable<Drawable> obj);
    public delegate void LogicHandler(IEnumerable<Actionable> obj);

    public static void gameloop(DrawHandler draw,LogicHandler action){

        List<Player> list = new List<Player>(){
            new Player()
        };

        for(int rounds = 0; rounds < 500; rounds++){
            draw(list);
            action(list);
        }

    }
    public static void Main()
    {
        gameloop(
             list =>{
                foreach(var item in list){
                    item.Draw();
                }
            },
            list =>{
                foreach(var item in list){
                    item.Do();
                }
            }
        );
    }
}

天真,我试图做一些与生锈相同的事情!

trait Drawable {
    fn draw(&self) {
        println!("draw object");
    }
}

trait Actionable {
    fn do_action(&self, action: &String) {
        println!("Do {}", action);
    }
}

#[derive(Debug)]
struct Position {
    x: u32,
    y: u32,
}
impl Position {
    fn new(x: u32, y: u32) -> Position {
        Position { x, y }
    }
}
#[derive(Debug)]
struct Player {
    pos: Position,
    name: String,
}

impl Player {
    fn new(name: String) -> Player {
        Player {
            name,
            pos: Position::new(0, 0),
        }
    }
}

impl Drawable for Player {
    fn draw(&self) {
        println!("{:?}", self);
    }
}

impl Actionable for Player {
    fn do_action(&self, action: &String) {
        println!("Do {} {}!", action, self.name);
    }
}

type DrawHandler = fn(drawables: &Vec<&dyn Drawable>) -> Result<(), String>;
type LogicHandler = fn(actions: &Vec<&dyn Actionable>) -> Result<(), String>;
type EventHandler = fn(events: &mut sdl2::EventPump) -> Result<bool, String>;

fn game_loop(
    window: &mut windowContext,
    draw_handler: DrawHandler,
    event_handler: EventHandler,
    logic_handler: LogicHandler,
) -> Result<(), String> {
    let mut objects: Vec<&Player> = Vec::new();

    objects.push(&Player::new("b".to_string()));

    while event_handler(&mut window.events)? {
        logic_handler(&objects)?; // Does Not work

        window.canvas.clear();

        draw_handler(&objects)?; // Does Not Work
        window.canvas.present();
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
    }

    Ok(())
}

如果不可能的话,与C#版本相比,生锈的等效值是多少?

我接受这是不可能的。我想知道在锈中使用了什么

今天,我了解到,锈仅在其返回类型为协变时不支持fn参数的协方差。 (请参阅rust doc)为什么我了解到有关rust的事实?因为我试图实现...

c# rust covariance
1个回答
1
投票

在Rust中,隐式完成的工作很少,这包括您发现的转换。

© www.soinside.com 2019 - 2024. All rights reserved.