2014-06-04 1 views

ответ

20

Нет, это не в настоящее время, и в то время как я думаю, что это, вероятно, что в конечном итоге будет реализован, это очень маловероятно, чтобы прийти до 1,0.

Типичная используемая здесь техника - это разные функции или методы с различными сигнатурами.

+2

Неужели это еще не так? – bge0

+0

Такая особенность еще не указана, не говоря уже о внедрении. –

+9

Что-то изменилось? Благодарю. –

17

Нет, Rust не поддерживает аргументы функции по умолчанию. Вы должны определить разные методы с разными именами. Также нет функции перегрузки, потому что Rust использует имена функций для получения типов (для перегрузки функций требуется обратное).

В случае инициализации структуры можно использовать синтаксис обновления структуры, как это:

use std::default::Default; 

#[derive(Debug)] 
pub struct Sample { 
    a: u32, 
    b: u32, 
    c: u32, 
} 

impl Default for Sample { 
    fn default() -> Self { 
     Sample { a: 2, b: 4, c: 6} 
    } 
} 

fn main() { 
    let s = Sample { c: 23, .. Sample::default() }; 
    println!("{:?}", s); 
} 

[по запросу, я перекрестно-отправил этот ответ с дублированным вопросом]

26

Поскольку аргументы умолчанию не являются при поддержке вы можете получить подобное поведение, используя Option<T>

fn add(a: Option<i32>, b: Option<i32>) -> i32 { 
    a.unwrap_or(1) + b.unwrap_or(2) 
} 

Это достигает цели, имеющие значение по умолчанию и функция кодируется только один раз (а не в каждом вызове), но, конечно, намного больше, чтобы напечатать. Вызов функции будет выглядеть как add(None, None), что вам может или не понравится в зависимости от вашей перспективы.

Если вы видите, что ничего не вводите в список аргументов, поскольку кодер потенциально забывает сделать выбор, тогда большое преимущество здесь проявляется в явном выражении; вызывающий явно заявляет, что хочет пойти со своим значением по умолчанию и получит ошибку компиляции, если ничего не поместит. Подумайте об этом, набрав add(DefaultValue, DefaultValue).

UPDATE:

Вы также можете использовать макрос!

fn add(a: i32, b: i32) -> i32 { a + b } 

macro_rules! add { 
    ($a: expr) => { add($a, 2) }; 
    () => { add(1, 2) } 
} 

assert_eq!(add!(), 3); 
assert_eq!(add!(4), 6); 

Большая разница между двумя решениями является то, что с «Option» -al рассуждениях полностью действует писать add(None, Some(4)), но с макро сопоставления с образцом вы не можете (это аналогично правилам аргументов по умолчанию языка Python).

1

Если вы используете Rust 1,12 или более поздней версии, вы можете по крайней мере сделать аргументы функции проще в использовании с Option и into():

fn add<T: Into<Option<u32>>>(a: u32, b: T) -> u32 { 
    if let Some(b) = b.into() { 
     a + b 
    } else { 
     a 
    } 
} 

fn main() { 
    assert_eq!(add(3, 4), 7); 
    assert_eq!(add(8, None), 8); 
} 
+1

В то время как технически точная, сообщество Rust разделено по-разному на том, является ли это «хорошей» идеей. Я лично попадаю в «нехороший» лагерь. – Shepmaster

+0

@Shepmaster он может увеличить размер кода, и он не является сверх читабельным. Являются ли возражения против использования этого шаблона? Я до сих пор нашел, что компромиссы будут полезны в обслуживании эргономических API, но подумал бы, что я мог бы пропустить некоторые другие ошибки. – squidpickles