Необязательный аргумент функции, указанный как признак вместо конкретного типа

Я смотрел Rust последние несколько месяцев, но я только начал заниматься настоящим проектом. Я не уверен, что терминология в названии верна. Пожалуйста, дайте мне знать, как это можно исправить.

Я пишу оболочку для библиотеки ENet (http://enet.bespin.org). Моя цель - сохранить максимально похожий API rust на API C, за исключением функций рефакторинга, которые переводят указатели дескрипторов стиля C в функции-члены структурных объектов. Я хочу, чтобы API оставался похожим, чтобы официальная документация C одинаково хорошо применялась к оболочке ржавчины.

ENet предоставляет единственную функцию для создания хоста клиента или хоста сервера. При создании сервера вы передаете функции указатель на структуру IP-адреса. При создании клиента вы передаете NULL.

Я пытаюсь имитировать такое поведение, используя черту ToSocketAddr и Option, но у меня возникают проблемы, когда я использую их вместе.

Это сокращенный пример того, что я пытаюсь сделать:

use std::io::net::ip::ToSocketAddr;

fn create_host<A: ToSocketAddr>(addr: Option<A>) {
    match addr {
        Some(a) => println!("Address is {}. Return a server host object.",a.to_socket_addr()),
        None    => println!("no address... Return a client.")
    };
}


fn main() {
    create_host(Some("localhost:12345"));
    create_host(None);
}

Первый вызов create_host() работает как шарм. Однако второй вызов не будет компилироваться.

Rustc возвращается

error: unable to infer enough type information about `_`; type annotations required

Я предполагаю, что эта ошибка возникает из-за того, что None не разрешает общий A. Я пробовал следующее, но это тоже не сработало, потому что ToSocketAddr не реализует черту core::kinds::Sized.

fn create_host(addr: Option<ToSocketAddr>) {
    ...
}

Есть ли способ сделать это или мне нужно использовать другой подход?


person Mark E. McDermott    schedule 03.12.2014    source источник


Ответы (1)


fn main() {
    create_host(Some("localhost:12345"));
    create_host(None::<&str>);
}

Я выбрал &str здесь, так как это тот же тип, что и при первом вызове, чтобы компилятор не генерировал другую мономорфизированную версию универсальной функции. Вы можете выбрать любой тип, реализующий ToSocketAddr.

person Francis Gagné    schedule 04.12.2014
comment
Спасибо, это сработало! До сих пор я не видел, чтобы этот синтаксис применялся к None ни в каких примерах. У вас есть ссылки, которые точно объясняют, почему и как это работает? - person Mark E. McDermott; 04.12.2014
comment
См. Пути и Общие функции в Справочнике по Rust. None не является универсальной функцией, а скорее универсальной / полиморфной константой, но синтаксис списка аргументов типа по-прежнему применяется. - person Francis Gagné; 04.12.2014
comment
Спасибо, помогли. - person Mark E. McDermott; 04.12.2014