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)]