рдкрд╛рд░реНрд╕, рдорд╛рдиреНрдп рдирд╣реАрдВ

рджрд┐рд╕рдВрдмрд░ рдореЗрдВ рд╡рд╛рдкрд╕, рдореИрдВ рдЕрдВрдЧреНрд░реЗрдЬреА рдореЗрдВ рдПрдХ рдмрд┐рд▓реНрдХреБрд▓ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдЖрдпрд╛ рдерд╛, рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдмрдврд╝рд╛рдиреЗ рдФрд░ рд░реАрдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рднрд╛рд╖рд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рдерд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЙрд╕ рд╕рдордп рдореИрдВ рд╡рд╛рдпреБрд╕реЗрдирд╛ рдкрд░ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдмрд╣реБрдд рд╡реНрдпрд╕реНрдд рдерд╛, рдЬрд┐рд╕реЗ рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдерд╛, рдЬрдмрдХрд┐ рдпрд╛рджреЗрдВ рдЕрднреА рднреА рддрд╛рдЬрд╛ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдм, рдЬрдм рдореИрдВрдиреЗ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд┐рдпрд╛, рддреЛ рдореИрдВ рдЕрдВрдд рдореЗрдВ рдЗрд╕ рдЕрджреНрднреБрдд рдиреЛрдЯ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛ рдЧрдпрд╛ред рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдореВрд▓ рднрд╛рд╖рд╛ рд╣рд╛рд╕реНрдХреЗрд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рджрд░реНрд╢рдХреЛрдВ рдХреА рд╡реНрдпрд╛рдкрдХ рдкрд╣реБрдВрдЪ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдПрдХ рд░реИрд╕реНрдЯ рдореЗрдВ рдХреЙрдкреА рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣рд╛рдВ рдХреА рднрд╛рд╖рд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╣рддреНрд╡рд╣реАрди рд╣реИ, рдЗрд╕ рд▓реЗрдЦ рдХреА рдпреБрдХреНрддрд┐рдпрд╛рдВ рдореИрдВ рджреИрдирд┐рдХ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ "рд╕рд╛рдВрд╕рд╛рд░рд┐рдХ" рд╕реА # рдФрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдмрд╕ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдФрд░ рд╕рдорд░реНрдерд┐рдд рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ, рднрд╛рд╖рд╛ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛, рд▓реЗрдЦ рд╡рд┐рд╖рдп рдореЗрдВ рд╣реЛрдЧрд╛ред


рдкреНрд░реВрдлрд░реАрдбрд┐рдВрдЧ рдФрд░ рдЕрдиреБрд╡рд╛рдж рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред Hirrolot, funkill рддрдерд╛ andreevlex



рд╕рдордп рдХреА рдПрдХ рд▓рдВрдмреА рдЕрд╡рдзрд┐ рдореЗрдВ, рдореИрдВ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдЯреАрдХ, рд╕рд░рд▓ рддрд░реАрдХрд╛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдШрд░реНрд╖ рдХрд┐рдпрд╛ рдХрд┐ рдЯрд╛рдЗрдк-рдбреНрд░рд┐рд╡реЗрди рдбрд┐рдЬрд╝рд╛рдЗрди рдХреНрдпрд╛ рд╣реИ ( рдЗрд╕рдХреЗ рдмрд╛рдж - рдЯрд╛рдЗрдкрдбреАрдбреА, рд▓рдЧрднрдЧред рдЯреНрд░рд╛рдВрд╕ред )ред рдХрд╛рдлреА рдмрд╛рд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдореБрдЭрд╕реЗ рдкреВрдЫрд╛ рдХрд┐ "рдЖрдк рдЗрд╕ рддрд░рд╣ рдХрд╛ рдирд┐рд░реНрдгрдп рдХреИрд╕реЗ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ?", рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рдХреЛрдИ рд╕рдВрддреЛрд╖рдЬрдирдХ рдЬрд╡рд╛рдм рдирд╣реАрдВ рдерд╛ред рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рджреГрд╖реНрдЯрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ рдерд╛: рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдбрд┐рдЬрд╛рдЗрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдереА рдЬреЛ рдореБрдЭреЗ "рд╕рд╣реА" рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдирд╣реАрдВ рдХрд░рддреА рдереА, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдореИрдВ рджреВрд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реВрдВред


: JSON , , . , , , TypeDD, , , :


, .


TypeDD


, : TypeDD, , , . , . , , , .



, , , " ?". :


enum Void {}

fn foo(x: i32) -> Void

? , тАФ , .. Void тАФ , , Void. , , :


fn head<T>(xs: Vec<T>) -> T

. ? , - , , :


fn head<T>(xs: Vec<T>) -> T {
    match xs.as_slice() {
        [x, ..] => *x
    }
}

error[E0004]: non-exhaustive patterns: `&[]` not covered
 --> src/lib.rs:2:11
  |
2 |     match xs.as_slice() {
  |           ^^^^^^^^^^^^^ pattern `&[]` not covered
  |

, , , . , , [], . , .. , , , ! , , , ( , . .).



- . , . , " " - , . head, , .



, head , .. : , . , : . , , , , : , , . Rust Option:


fn head<T>(xs: Vec<T>) -> Option<T>

, head тАФ None, , T:


fn head<T>(xs: Vec<T>) -> Option<T> {
    match xs.as_slice() {
        [x, ..] => Some(*x),
        [] => None,
    }
}

, ? , тАФ тАж .


Option, , , head. . head None, , . , :


fn get_configuration_directories() -> Result<Vec<String>, &'static str> {
    let config_dirs_string = std::env::var("CONFIG_DIRS").map_err(|_| "cannot read env")?;
    let list: Vec<_> = config_dirs_string.split(',').map(|x| x.to_string()).collect();
    if list.is_empty() {
        return Err("CONFIG_DIRS cannot be empty");
    }
    Ok(list)
}

fn main() -> Result<(), &'static str> {
    let config_dirs = get_configuration_directories()?;
    match head(config_dirs) {
        Some(cacheDir) => initialize_cache(cacheDir),
        None => panic!("should never happen; already checked config_dirs is non-empty")
    }
    Ok(())
}

get_configuration_directories , . head main, , Option<&str> None, , , ! :


  1. -, . , , ?


  2. -, . , , , , , .


  3. , , . , get_configuration_directories , , , ? , main, "" , .



. None , get_configuration_directories .
, , .



, head , . , - : , , head , , , . ?


() head .


fn head<T>(xs: Vec<T>) -> T

, . , , : ( тАФ Vec<T>). , head .


, , .
, NonEmptyVec . :


struct NonEmptyVec<T>(T, Vec<T>);

, NonEmptyVec тАФ T (, ) Vec<T>. , Vec<T> [], . , head :


fn head<T>(xs: NonEmptyVec<T>) -> T {
    xs.0
}

, , , , . :


fn get_configuration_directories() -> Result<NonEmptyVec<String>, &'static str> {
    let config_dirs_string = std::env::var("CONFIG_DIRS").map_err(|_| "cannot read env")?;
    let list: Vec<_> = config_dirs_string.split(',').map(|x| x.to_string()).collect();
    match non_empty(list) {
        Some(x) => Ok(x),
        None => Err("CONFIG_DIRS cannot be empty")
    }
}

fn main() -> Result<(), &'static str> {
    let config_dirs = get_configuration_directories()?;
    initialize_cache(head(config_dirs));
    Ok(())
}

, main ! , get_configuration_directories. NonEmptyVec Vec non_empty, :


fn non_empty<T>(list: Vec<T>) -> Option<NonEmptyVec<T>>

, Option , None : . , NonEmptyVec, ( !) , . , NonEmptyVec Vec<T> , .


head , :


  • , .


  • , get_configuration_directories , . , main , !



, head , non_empty:


fn old_head<T>(xs: Vec<T>) -> Option<T> {
    non_empty(xs).map(head)
}

, : head . , .



? , тАФ , , . , : , , . :


fn validate_non_empty<T>(xs: Vec<T>) -> Result<(), UserError> {
    if !xs.is_empty() {
        Ok(())
    } else {
        Err(UserError::new("list cannot be empty"))
    }
}

fn parse_non_empty<T>(mut xs: Vec<T>) -> Result<NonEmptyVec<T>, UserError> {
    if !xs.is_empty() {
        let head = xs.remove(0);
        Ok(NonEmptyVec(head, xs))
    } else {
        Err(UserError::new("list cannot be empty"))
    }
}

: , , . : validate_non_empty (), , , parse_non_empty NonEmptyVec<T>, , . , parse_non_empty , validate_non_empty .


: validate_non_empty , parse_non_empty , . , parse_non_empty , , ", ". parse_non_empty. - , ? , , , , parse_non_empty , .


: ? , , , . , тАФ тАФ , - . , , , parse_non_empty : , .


: , , , ! Rust , :



: . - -, , . , , , , , .


, , : , . : - , . , NonEmpty : , .



, , , . , ? , , , ?


, . Ad-hoc , - . 2016 The Seven Turrets of Babel: A Taxonomy of LangSec Errors and How to Expunge Them :


тАФ , , , ; , ( - ), "" .

, :


, . , - , .

, , , , , , , . тАФ , , , тАФ .


, тАФ , , . , , , , "" . , , .


, : , , , . , .


, ,


, . ", , !", , , . "" "", "".


: .


, , , , , - . тАФ , , :


fn check_no_duplicate_keys<K: Eq, V>(xs: &[(K,V)]) { ... }

"" тАФ : . - , , , . , , , HashMap. , HashMap , , .


, , , , , . - , HashMap . , , , . check_no_duplicate_keys:


fn check_no_duplicate_keys<K: Eq, V>(xs: &[(K,V)]) -> HashMap<K,V> { ... }

, !


:


  1. , . , . , , .


  2. , . , . , , , .


    , . - , .



, , , , . , , - . , - !


, :


  • , . bool , ( , , . .). , тАФ , , ,


  • Result<(), Error> . , - , , .


  • . , , , , , , . тАФ -.


  • , , : .


    • . , , , .

  • , " " . , , , , , . (newtype) , - .



, . , error "impossible" - тАФ , , . , , .



, -. , , тАФ ! , .


. , тАФ " " тАФ . , , , . , тАФ ! тАФ . , тАФ .


, , : Type Safety Back and Forth. , . Ghosts of Departed Proofs, , , .


, , , . , тАФ , . , TypeDD, , , , . , , . , тАФ .





, тАФ , .


All Articles