A Prefix Chapter
Rust の細々としたところのメモ。
vscode
language server
https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer
debugger
https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb
launch.json
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"cargo": {
"args": [
"build",
]
},
"args": [],
"cwd": "${workspaceFolder}"
}
String
utf-8 のバイト列を内部に持つ。
- String
- &str
- &[u8] UTF-8バイト列
String と &str
utf8バイト列を所有するのが Vec<u8>
String で、それへのスライス?が &str
。
&str から 作る
let text: String = String::from("hoge");
let text: String = "hoge".to_string();
let text: String = "hoge".to_owned();
&str にする
src.as_str();
Literal
文字列リテラルは、static な lifetime を持つ &str
。
let text: &'static str = "text";
utf-8 バイト列 &[u8]
str::from_utf8(slice::from_raw_parts(source, source_size)).unwrap().to_owned()
文字列からその他の型への変換
use std::str::FromStr
if let Ok(num) = i32::from_str("123") {
}
else{
// 失敗し得る
}
CString
- CString
- &cstr
- \0で終端したUTF-8とは限らないバイト列
// \0で終端した `char*` から作成する
let renderer = unsafe {
let p = gl::GetString(gl::RENDERER); // *const u8
CStr::from_ptr(p as *const i8)
};
println!("Renderer: {}", renderer.to_string_lossy());
OSString
https://doc.rust-lang.org/std/ffi/struct.OsString.html
http://d.sunnyone.org/2015/06/rustwindowslpcwstr-lpwstr.html
- wchar_t
fn from_wide_ptr(ptr: *const u16) -> String {
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt;
unsafe {
assert!(!ptr.is_null());
let len = (0..std::isize::MAX).position(|i| *ptr.offset(i) == 0).unwrap();
let slice = std::slice::from_raw_parts(ptr, len);
OsString::from_wide(slice).to_string_lossy().into_owned()
}
}
Path
Args
let args: Vec<String> = std::env::args().collect();
Vec
中身の移動
drain
#![allow(unused)] fn main() { let src: Vec<i32> = vec![1, 2, 3]; let dst: Vec<i2> = src.drain(..).collect(); }
Option
中身の移動
take
#![allow(unused)] fn main() { let src: Option<i32> = Some(1); let dst: Option<i32> = src.take(); }
中身を参照化
#![allow(unused)] fn main() { let src: Option<i32> = Some(1); let dst: Option<&i32> = src.as_ref(); }
Result
##エラーの型を変える
#![allow(unused)] fn main() { map_error }
Iterator
iterator を返す関数
#![allow(unused)] fn main() { -> impl Iteraotr<Item = i32> { } }
fs
fn read_file<P>(path_arg: P) -> std::io::Result<Vec<u8>>
where
P: AsRef<std::path::Path>,
{
let path = path_arg.as_ref();
let mut file = std::fs::File::open(path)?;
use std::io::Read;
let mut contents: Vec<u8> = Vec::new();
file.read_to_end(&mut contents).map(|_| contents)
}
Rc
コレクション(Vec, HashMap)、または Option の中に入れて、 中身を clone して返すことで、入れ物への borrow を早期に終了させる。
中身
#![allow(unused)] fn main() { let src: Rc<Option<i32>> = Rc::new(Some(1)); // * deref(Option<i32>) して、 // & 参照する(&Option<i32>) if let Some(i) = &*src { } }
#![allow(unused)] fn main() { let src: Rc<Option<i32>> = Rc::new(Some(1)); let src2: &Rc<Option<i32>> = &src; // * deref して(Rc<Option<i32>>)、 // * deref して(Option<i32>)、 // & 参照する(&Option<i32>) if let Some(i) = &**src2 { } }
RefCell
中身の代入
replace
#![allow(unused)] fn main() { let r = RefCell::new(1); r.replace(2); }
allow
警告抑止
#![allow(xxx)
コード全体に効果#[allow(xxx)]
次の要素に効果
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]