Conditional structures: Difference between revisions

Content added Content deleted
(Added FreeBASIC)
(→‎{{header|Rust}}: Added Rust)
Line 4,327: Line 4,327:


end select</lang>
end select</lang>

=={{header|Rust}}==
===Compile-Time===
====Conditional compilation====
Rust supports conditional compilation via the `cfg`.
<lang rust>// This function will only be compiled if we are compiling on Linux
#[cfg(target_os = "linux")]
fn running_linux() {
println!("This is linux");
}
#[cfg(not(target_os = "linux"))]
fn running_linux() {
println!("This is not linux");
}

// If we are on linux, we must be using glibc
#[cfg_attr(target_os = "linux", target_env = "gnu")]
// We must either be compiling for ARM or on a little endian machine that doesn't have 32-bit pointers pointers, on a
// UNIX like OS and only if we are doing a test build
#[cfg(all(
any(target_arch = "arm", target_endian = "little"),
not(target_pointer_width = "32"),
unix,
test
))]
fn highly_specific_function() {}
</lang rust>
Conditional compilation may also be achieved via the `cfg!` macro.
<lang rust>fn main() {
if cfg!(target_os = "linux") {
// Do something
}
}</lang>

====Generics (static dispatch)====
By default, generics in Rust are monomorphized, so no vtable lookups at runtime are necessary.
<lang rust>trait PrintType {
fn print_type();
}

impl PrintType for char {
fn print_type() {
println!("char");
}
}

impl PrintType for f64 {
fn print_type() {
println!("64-bit float");
}
}

fn prints_type_of_args<T,U>(arg1: T, arg2: U)
where T: PrintType
U: PrintType
{
arg1.print_type();
arg2.print_type();
}

fn main() {
prints_type_of_args('a', 2.0);
prints_type_of_args('a', 'b');
}</lang>
===Runtime===
====If-statement====
<lang rust>if some_conditional {
do_stuff();
} else if some_other_conditional
do_other_stuff();
} else {
destroy_humanity();
}

// If statements are also expressions and will yield the value of the last expression in each block
let x = if y > z { y + 1 } else { z * 4 };

// Pattern matching may also be used
struct Point {
x: i32,
y: i32,
}
fn some_function(p: Option<Point>) {
if let Some(Point { x: x_coord, y: y_coord }) = p {
// Do something with x_coord and y_coord
}
}</lang>
====Match statement====
Match statements are essentially more powerful switch statements
<lang rust>fn some_other_function(p: Option<Point>) {
match p {
Some(Point { x: 0, y: 0 }) => println!("Point is on origin"),
Some(Point { x: 0, y: _ }) | Some(Point { x: _, y: 0 }) => println!("Point is on an axis"),
Some(Point {x: a, y: b}) if a == b println!("x and y are the same value"),
Some(Point {x: ref mut a, y: ref b}) if x > 4 && y < 2 => println!("we got a mutable reference to x-value and an immutable reference to y-value."),
op @ Some(p) => println!("op is the Option<Point> while p is the contained Point"),
None => println!("We didn't get a point"),
}
}</lang>
====Generics (dynamic dispatch)====
Generics may also be accomplished via dynamic dispatch, so the actual code that is run is determined at compile time.
Using the same trait defined in the static dispatch section:
<lang rust>fn prints_args_dynamic(arg1: &PrintType, arg2: &PrintType) {
arg1.print_type();
arg2.print_type();
}
fn main() {
prints_args_dynamic(&'a', &2.0);
prints_args_dynamic(&6.3,&'c');
}</lang>


=={{header|Sather}}==
=={{header|Sather}}==