ズボンの左か右ポケットに入れる
後ろのポケットや、ジャケットには入れない。何らかの拍子に飛び出して落ちることがある。
カバンに入れない
財布を取り出そうとしたタイミングで落ちたりするので、カバンには入れない
対策としてカバンの横にスマホ専用ポーチをつけておくと良い
スマホを持たない
スマホを持たなければ、落ちない
後ろのポケットや、ジャケットには入れない。何らかの拍子に飛び出して落ちることがある。
財布を取り出そうとしたタイミングで落ちたりするので、カバンには入れない
対策としてカバンの横にスマホ専用ポーチをつけておくと良い
スマホを持たなければ、落ちない
結構昔はお世話になってたんですが、最近ではSEOの食い物にされているなぁという感想しか出てこない。特に、アフィリエイトサイトなどで、何らかの方法ではてなブックマークを大量につけているメディアが目立つようになってきた。アフィリエイトでもとりわけ還元率が高いクレジットカードなどのブログ記事がよく流れてくる。
ある日、Yahooのトップページがホッテントリ入りした。原因はスパムアカウントと思われるアカウントが大量にハテブをしたことが原因。おそらく何らかのハテブを自動的につけてホッテントリ入りさせてくれる情報商材系ツールが、お試しで使われているように見える。
もし、このはてぶ自動増殖ツールXがこれからも使われ続けて、はてなが対策しなかったらホッテントリは意味をなさなくなってきそう・・。
日本でもGoogle Homeを初め、AIスピーカーが普及し始めてきました。音声認識や音声合成の技術は、各社が開発しやすいように用意されているようです。
まだ、日本で登場して間もないですが、いち早く食べログによる近くのおすすめのお店を教えてくれる機能や、ピカチュウと話しかけるとピカチュウと会話できる機能(Google Home)おもしろい機能も増えてきました。その際、AIの声も変わるのでAIが交代して話しているように聞こえるので面白いです。
さて、こうしたAIスピーカーですが、最新のニュースや話題を音声でお届けするニュースAIももちろんありますが、それは予め用意された原稿をAIが読み上げているにすぎない状態です。こうしたAIによるニュース配信が、もし個人に特化したニュースや話題の提供に進化したとしたらどうでしょう。すでにアプリ市場では、スマートニュースやグノシーなどが個人の趣味嗜好に特化したニュースや話題の配信を行っています。そのように、ニュースや話題の配信を個人にレコメンドして配信できたら朝の時間を有意義に過ごせるように思うのです。
スレッドがコケたときに、スレッドの名前が表示される。エラー時の原因特定に便利。
use std::thread; thread::Builder::new() .name("thread name".to_string()) .spawn(move || { println!("Hello, world!"); });
flat_map だと、 cloned()
しないと、 Option<&String>
になってエラーになる。Vec<String>
として取り出したい場合は、 cloned()
をつける。
let result: Vec<String> = vec![Some("hoge".to_owned()), None] .iter() .flat_map( |f| f ) .cloned() .collect(); println!("{:?}", result);
https://doc.rust-lang.org/std/option/enum.Option.html の補足追記です。
この記事は MIT ライセンスです。
Someならtrue
let x: Option<u32> = Some(2); assert_eq!(x.is_some(), true); let x: Option<u32> = None; assert_eq!(x.is_some(), false);
Noneならtrue
let x: Option<u32> = Some(2); assert_eq!(x.is_none(), false); let x: Option<u32> = None; assert_eq!(x.is_none(), true);
Option
borrow は発生しません。
let num_as_str: Option<String> = Some("10".to_string()); // First, cast `Option<String>` to `Option<&String>` with `as_ref`, // then consume *that* with `map`, leaving `num_as_str` on the stack. let num_as_int: Option<usize> = num_as_str.as_ref().map(|n| n.len()); println!("still can print num_as_str: {:?}", num_as_str);
Option
let mut x = Some(2); match x.as_mut() { Some(v) => *v = 42, None => {}, } assert_eq!(x, Some(42));
オプションをアンラップし、Someの中身を返す。
unwrapと異なる点は、panicが発生した場合に、msgが流れる
let x = Some("value"); assert_eq!(x.expect("the world is ending"), "value");
Some(v) から vを取り出す。
もとの変数からは移動されてしまうので注意。
Noneだった場合はpanicが発生する
let x: Option<&str> = None; x.expect("the world is ending"); // panics with `the world is ending`
アンラップ時に、Noneだった場合は、orで指定したものを返す。制約として同じ型のものでなければいけない。
assert_eq!(Some("car").unwrap_or("bike"), "car"); assert_eq!(None.unwrap_or("bike"), "bike");
アンラップ時にNoneだった場合は、or_elseで指定したクロージャの結果を返す。
let k = 10; assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4); assert_eq!(None.unwrap_or_else(|| 2 * k), 20);
アンラップ時にSomeだった場合は、Some(v)のvをクロージャに渡し、結果をSome(s)として受け取る。Noneだった場合はそのままNoneになる。
アンラップ時にSomeだった場合は、Some(v)のvをクロージャに渡し、結果をsとして受け取る。Noneだった場合はデフォルト値が渡される。結果sとデフォルト値は同じ型。
let x = Some("foo"); assert_eq!(x.map_or(42, |v| v.len()), 3); let x: Option<&str> = None; assert_eq!(x.map_or(42, |v| v.len()), 42);
Someだった場合もNoneだった場合もクロージャに渡す。結果の型はそれぞれのクロージャで同じでなければいけない。
let k = 21; let x = Some("foo"); assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3); let x: Option<&str> = None; assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42);
Option型をResult型に変換する。失敗だった場合の処理は新たに追加する。
let x = Some("foo"); assert_eq!(x.ok_or(0), Ok("foo")); let x: Option<&str> = None; assert_eq!(x.ok_or(0), Err(0));
Option型をResult型に変換する。失敗だった場合の処理は、クロージャで計算する。
let x = Some("foo"); assert_eq!(x.ok_or_else(|| 0), Ok("foo")); let x: Option<&str> = None; assert_eq!(x.ok_or_else(|| 0), Err(0));
イテレータに変換する。next()すると結果が変える。
二回next()するとNoneになる。
let x = Some(4); assert_eq!(x.iter().next(), Some(&4)); let x: Option<u32> = None; assert_eq!(x.iter().next(), None);
iterと一緒だが、ミュータブル
let mut x = Some(4); match x.iter_mut().next() { Some(v) => *v = 42, None => {}, } assert_eq!(x, Some(42)); let mut x: Option<u32> = None; assert_eq!(x.iter_mut().next(), None);
引数の条件もSomeでなければ、全体的にNoneになる。
let x = Some(2); let y: Option<&str> = None; assert_eq!(x.and(y), None); let x: Option<u32> = None; let y = Some("foo"); assert_eq!(x.and(y), None); let x = Some(2); let y = Some("foo"); assert_eq!(x.and(y), Some("foo")); let x: Option<u32> = None; let y: Option<&str> = None; assert_eq!(x.and(y), None);
NoneのときはNoneを返すが、Someだった場合は、クロージャの計算結果を Some<U>
として返す。
fn sq(x: u32) -> Option<u32> { Some(x * x) } fn nope(_: u32) -> Option<u32> { None } assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16)); assert_eq!(Some(2).and_then(sq).and_then(nope), None); assert_eq!(Some(2).and_then(nope).and_then(sq), None); assert_eq!(None.and_then(sq).and_then(sq), None);
どちらかに値が入っていれば、最初にHITした値が帰る
let x = Some(2); let y = None; assert_eq!(x.or(y), Some(2)); let x = None; let y = Some(100); assert_eq!(x.or(y), Some(100)); let x = Some(2); let y = Some(100); assert_eq!(x.or(y), Some(2)); let x: Option<u32> = None; let y = None; assert_eq!(x.or(y), None);
値が含まれていればSomeを返すが、含まれていない場合は、クロージャが呼ばれその結果を返す。クロージャの結果はSomeかNoneである。
fn nobody() -> Option<&'static str> { None } fn vikings() -> Option<&'static str> { Some("vikings") } assert_eq!(Some("barbarians").or_else(vikings), Some("barbarians")); assert_eq!(None.or_else(vikings), Some("vikings")); assert_eq!(None.or_else(nobody), None);
Nonen場合は、vをオプションに挿入し、含まれている値への変更可能な参照を返す。
let mut x = None; { let y: &mut u32 = x.get_or_insert(5); assert_eq!(y, &5); *y = 7; } assert_eq!(x, Some(7));
Noneの場合、クロージャによって計算された値をオプションに挿入し、含まれている値への変更可能な参照を返す。
let mut x = None; { let y: &mut u32 = x.get_or_insert_with(|| 5); assert_eq!(y, &5); *y = 7; } assert_eq!(x, Some(7));
オプションから値を取り除き、Noneをその場所に残す。
let mut x = Some(2); x.take(); assert_eq!(x, None); let mut x: Option<u32> = None; x.take(); assert_eq!(x, None);
Polyは CC-BYという緩いライセンスで3D素材(作品)を公開できる3Dプラットフォーム。自身の作品もアップロードすることができて、他人の作品にいいねもできる。
3D素材(作品)は、著作権表示をすれば自由に利用することができる。ARやVRが加速してきているのでこういった素材サイトで、ぐっと開発の敷居が下がるような気がしている。
予め調べてなかったのが悪いんだけど普段Plus使いなので、この情報はキツイ。
それまでに、iPhoneX Plusと iPhone X 分稼がなくてはいけない。。
あ、そうか。稼げばいいのだ。
iPhone X Plusを1年待つなんて無理だし、何よりVRと相性がいい有機ELを無視できない。
有機ELは、応答速度が速いのでVR酔いが起きにくく、様々なHMDで使われている。
すでにARKitを使ったVRゲームも出ているので、すぐにでも開発したい!
今は、 poly という3D素材のプラットフォームがあるので、これを参考にして何か作ってみようと思っている。
こういう感じで言うといける。わざわざプレイリストを作らなくても良いです。
半年ほど悩んでいたのですがやっと解決できたのでまとめます。
WebsocketではHTTPをUpgradeしたプロトコルとして扱われ、COMETとは違いajaxやiframeなどによるコネクションをポーリングする技術とは異なる双方向通信を実現するプロトコルです。
なのでWebsocket自体に予約されたポートは無く、クライアントからは80や443で通信することも可能です。といっても、サーバー側がWebsocketに対応している必要があります。
例えばストリーミングを行うAPIがあったとします。
/api/v1/streaming
このAPIのリクエスト時に、 http://(https://)であれば、 COMET等の技術によりコネクションがポーリングされストリーミングで受信処理が行われる用にしたいが、
ws://(wss://) の場合は、websocketでストリーミングで受信処理を行わるようにしたい場合、Apacheでは下記のようにすると問題が出ます。
ProxyPass /api/v1/streaming/ ws://localhost:4000/ ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/ ProxyPass /api/v1/streaming/ http://localhost:4000/ ProxyPassReverse /api/v1/streaming/ http://localhost:4000/
これだと、最初のProxyPassで潰されてしまい、httpの通信に失敗してしまいます。
この場合、wsの場合はmod_rewriteを使うことで解決できます。
websocketは、ConnectionがUpgradeになるので、それをrewriteの条件に指定することでwebsocketの場合のみwsに接続するように変更する事ができます。
RewriteEngine On RewriteCond %{HTTP:Connection} Upgrade [NC] RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /api/v1/streaming/(.*) ws://localhost:4000/api/v1/streaming/$1 [P,L] ProxyPreserveHost On ProxyPass /api/v1/streaming/ http://localhost:4000/api/v1/streaming/ ProxyPassReverse /api/v1/streaming/ http://localhost:4000/api/v1/streaming/ ProxyPass / http://localhost:3000/ ProxyPassReverse / http://localhost:3000/