Возможно ли в Rust создать функцию с аргументом по умолчанию?Аргументы функции по умолчанию в Rust
fn add(a: int = 1, b: int = 2) { a + b }
Возможно ли в Rust создать функцию с аргументом по умолчанию?Аргументы функции по умолчанию в Rust
fn add(a: int = 1, b: int = 2) { a + b }
Нет, это не в настоящее время, и в то время как я думаю, что это, вероятно, что в конечном итоге будет реализован, это очень маловероятно, чтобы прийти до 1,0.
Типичная используемая здесь техника - это разные функции или методы с различными сигнатурами.
Неужели это еще не так? – bge0
Такая особенность еще не указана, не говоря уже о внедрении. –
Что-то изменилось? Благодарю. –
Нет, 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);
}
[по запросу, я перекрестно-отправил этот ответ с дублированным вопросом]
Поскольку аргументы умолчанию не являются при поддержке вы можете получить подобное поведение, используя 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).
Если вы используете 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);
}
В то время как технически точная, сообщество Rust разделено по-разному на том, является ли это «хорошей» идеей. Я лично попадаю в «нехороший» лагерь. – Shepmaster
@Shepmaster он может увеличить размер кода, и он не является сверх читабельным. Являются ли возражения против использования этого шаблона? Я до сих пор нашел, что компромиссы будут полезны в обслуживании эргономических API, но подумал бы, что я мог бы пропустить некоторые другие ошибки. – squidpickles
[# 6973] (https://github.com/mozilla/rust/issues/6973) содержит несколько обходов (с использованием структуры). – huon