2015-11-07 3 views
3

Rust новичок здесь. Что было бы хорошим способом динамического вывода наиболее вероятного типа с заданной строкой? Я пытаюсь закодировать функцию, которая задает строку, возвращает наиболее возможный тип, но я не знаю, с чего начать. В Python я, вероятно, использовал бы блок try-except. Это то, что я ожидаю иметь:Динамический вывод типа строки

"4" -> u32 (or u64) 
"askdjf" -> String 
"3.2" -> f64 

и так далее? Я знаю, что некоторые строки могут быть назначены нескольким возможным типам, поэтому проблема не определена, но меня интересует общая философия о том, как эффективно решить проблему в ржавчине.

ответ

5

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

Прежде всего: Rust статически типизирован, что означает, что функция возвращает один и только один тип, поэтому вы не можете просто возвращать разные типы, например, на динамически типизированных языках. Тем не менее, есть способы, чтобы имитировать динамическую типизацию, а именно - два (что я могу думать):

  1. enum: Если у вас есть фиксированное количество возможных типов, вы можете определить enum с одним из вариантов для каждого типа , как это:

    enum DynType { 
        Integer(i64), 
        Float(f32), 
        String(String), 
    } 
    
    fn dyn_parse(s: &str) -> DynType { 
        ... 
    } 
    

    Вы можете прочитать на enum с в this и следующей Rust главе книги.

  2. В стандартной библиотеке есть черта, предназначенная для имитации динамической типизации: Any. Существует дополнительная информация here. Ваш код может выглядеть следующим образом:

    fn dyn_parse(s: &str) -> Box<Any> { 
        ... 
    } 
    

    Вы не можете вернуть черту объекты непосредственно, так что вы должны положить его в Box.

Имейте в виду, что обе возможности требуют от пользователя вашей функции дополнительной отправки. Поскольку Rust статически типизирован, вы не можете делать то, к чему привыкли, на динамически типизированном языке.

Возможно, вам стоит попытаться решить свои проблемы по-другому, что имеет больше смысла в статически типизированном мире.


О части реализации: Как Фрэнсис Ганье сказал, есть parse, который пытается разобрать строку как тип программист определяет.Конечно, вы можете просто соединить эти звонки parse с разными типами и сделать первый, который преуспеет. Но это может быть не то, что вы хотите, и, возможно, не самая быстрая реализация.

Конечно, вы должны сначала подумать о точном правиле, какая строка должна анализировать как какой тип. После этого вы, например, можете построить конечный конечный автомат, который определяет тип строки. Однако делать это было бы сложно.

8

Существует метод parse на срезах строк (&str), который пытается проанализировать строку как конкретный тип. Однако вам придется знать конкретные типы, которые вы готовы обработать. Метод parse может возвращать значения любого типа, который реализует FromStr.

fn main() { 
    if let Ok(i) = "1".parse::<u32>() { 
     println!("{}", i); 
    } 
    if let Ok(f) = "1.1".parse::<f64>() { 
     println!("{}", f); 
    } 
} 

Обратите внимание, что ::<T> часть необходимо только, если компилятор не может сделать вывод, какой тип вы пытаетесь разобрать на (вы получите ошибку компилятора в этом случае).

Смежные вопросы