Rust에서 기본 인자로 함수를 만드는 것이 가능합니까?
fn add(a: int = 1, b: int = 2) { a + b }
Rust에서 기본 인자로 함수를 만드는 것이 가능합니까?
fn add(a: int = 1, b: int = 2) { a + b }
Option
하고 명시 적으로 전달해야 None
합니다.
답변:
아니요, 현재는 아닙니다. 언젠가는 구현 될 것 같지만 현재이 공간에서는 활발한 작업이 없습니다.
여기에 사용되는 일반적인 기술은 이름과 서명이 다른 함수 나 메서드를 사용하는 것입니다.
기본 인수가 지원되지 않기 때문에 다음을 사용하여 유사한 동작을 얻을 수 있습니다. 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)
.
매크로를 사용할 수도 있습니다.
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))
하지만 매크로 패턴이 일치하면 불가능하다는 것입니다 (파이썬의 기본 인수 규칙과 유사합니다).
"arguments"구조체와 From
/ Into
특성을 사용할 수도 있습니다 .
pub struct FooArgs {
a: f64,
b: i32,
}
impl Default for FooArgs {
fn default() -> Self {
FooArgs { a: 1.0, b: 1 }
}
}
impl From<()> for FooArgs {
fn from(_: ()) -> Self {
Self::default()
}
}
impl From<f64> for FooArgs {
fn from(a: f64) -> Self {
Self {
a: a,
..Self::default()
}
}
}
impl From<i32> for FooArgs {
fn from(b: i32) -> Self {
Self {
b: b,
..Self::default()
}
}
}
impl From<(f64, i32)> for FooArgs {
fn from((a, b): (f64, i32)) -> Self {
Self { a: a, b: b }
}
}
pub fn foo<A>(arg_like: A) -> f64
where
A: Into<FooArgs>,
{
let args = arg_like.into();
args.a * (args.b as f64)
}
fn main() {
println!("{}", foo(()));
println!("{}", foo(5.0));
println!("{}", foo(-3));
println!("{}", foo((2.0, 6)));
}
이 선택은 분명히 훨씬 더 많은 코드이지만 매크로 디자인과 달리 유형 시스템을 사용하므로 컴파일러 오류가 라이브러리 / API 사용자에게 더 도움이 될 것입니다. 이것은 또한 From
도움이되는 경우 사용자가 직접 구현할 수 있도록합니다.
아니요, 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);
}
[요청시 중복 질문에서이 답변을 교차 게시했습니다.]
Rust는 기본 함수 인수를 지원하지 않으며 앞으로 구현 될 것이라고 생각하지 않습니다. 그래서 매크로 형식으로 구현하기 위해 proc_macro duang 을 작성했습니다.
예를 들면 :
duang! ( fn add(a: i32 = 1, b: i32 = 2) -> i32 { a + b } );
fn main() {
assert_eq!(add!(b=3, a=4), 7);
assert_eq!(add!(6), 8);
assert_eq!(add(4,5), 9);
}
Rust 1.12 이상을 사용하고 있다면 최소한 함수 인자를 Option
and 와 함께 사용하기 쉽게 만들 수 있습니다 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);
}
또 다른 방법은 선택적 매개 변수를 사용하여 열거 형을 변형으로 선언하는 것입니다. 이는 각 옵션에 대해 올바른 유형을 사용하도록 매개 변수화 할 수 있습니다. 이 함수는 열거 형 변형의 가변 길이 조각을 가져 오도록 구현할 수 있습니다. 순서와 길이는 상관 없습니다. 기본값은 함수 내에서 초기 할당으로 구현됩니다.
enum FooOptions<'a> {
Height(f64),
Weight(f64),
Name(&'a str),
}
use FooOptions::*;
fn foo(args: &[FooOptions]) {
let mut height = 1.8;
let mut weight = 77.11;
let mut name = "unspecified".to_string();
for opt in args {
match opt {
Height(h) => height = *h,
Weight(w) => weight = *w,
Name(n) => name = n.to_string(),
}
}
println!(" name: {}\nweight: {} kg\nheight: {} m",
name, weight, height);
}
fn main() {
foo( &[ Weight(90.0), Name("Bob") ] );
}
산출:
name: Bob
weight: 90 kg
height: 1.8 m