ほしい
2019年6月にやったこと
引き続きSpring Security・OAuth2.0、OIDCあたりをごにょごにょしていた。 中国語がだれている。というか全体的にだれていた。
英語
English Bellを23レッスン受講した。 かなりダレてきたのでプランを軽いやつに変更した。 代わりに福利厚生でレアジョブができるようになったのでちょっとやってみている。
5月に受けたTOEICはR400、L350の750だった。受けるたびにReadingのスコアが伸びているが、それ以上にListningのスコアが落ちるので合計がどんどん下がっている。 なんで英会話しかやってないのにこうなるのか不思議だ。 あとは文法が全然ダメでPart7が9割くらい正解している人になっているので、文法をいい感じにするとRは450くらいを目指せる気がしている。Lはもうわからん。
OAuth徹底入門 セキュアな認可システムを適用するための原則と実践
token endpointにredirect_urlを送る理由とか、stateパラメータの存在意義とかがいまいちわからず、うーん???となっている。 あとはhttps://openid.net/specs/openid-connect-session-1_0.htmlを読んだりしていた。
情熱プログラマー
なんか気づいたら読み終わってた。
その他
Treviewの改修したりしてた。 https://github.com/inabajunmr/treview
これからやること
- 読書会プラットフォーム作る
- プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
- 読む
- ElectronかWebアプリ(サーバなし)でNature RemoのPC用クライアントを作る
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- あとはSPAとJSの学習用に
- 読書会プラットフォームの後
- あとはSPAとJSの学習用に
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- Goならわかるシステムプログラミング
- Kotlinがらみなんか
- Kotlinインアクションとか
- 英語
- 中国語
- ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
- なにがいいのかよくわからん
- Effective Go - The Go Programming Language
- パタヘネ
- スマホアプリ作る
- Clean Architecture 達人に学ぶソフトウェアの構造と設計
2019年5月にやったこと
Androidアプリがらみの資料とかみてた。 業務ではSpring SecurityとOAuth 2.0関連をごにょごにょしてた。あとDynamoDBとか。Spring Securityはフィルター。
Release It! 本番用ソフトウェア製品の設計とデプロイのために
読み終わった。Resilience4jで遊ぶ的なことを考えている。
英語
English Bellを39レッスン受講した。ステージ8がはじまった。 TOEICを受けたので直前にhttps://www.amazon.co.jp/dp/4023304603/を読んだ。 TOEICはRはまあまあでLが死んだ。結果は6月半ば。あとiKnowをサボってたのでちょこちょこやってた。
中国語
https://www.amazon.co.jp/dp/4863922191を読んでたが停滞している。四声が覚えられないストレスがやばい。 https://www.udemy.com/chinese-made-easy これを半分くらい見た。発音については本よりもレッスンのがいい。 本だと同じ音声をループするのがつらい。
6/23に中国語検定の準4級と4級を受けるが間に合うのか。
Kotlinのリファレンス読む
コルーチン以外の部分をざっくり読んだ。とりあえず一旦終わりにしてコードを書く。
OAuth徹底入門 セキュアな認可システムを適用するための原則と実践
ちまちま読んでる。OAuth2.0の各認可フローはだいたい頭に入ってるのでそのあたりはサクサク読んでる。
Android 入門読んだ
ざっくりわーっと動かしながら読んだ。 http://inabajunmr.hatenablog.com/entry/2019/05/05/182705
あとはサンプルアプリ眺めてなんとなく雰囲気を掴んだりした。 http://inabajunmr.hatenablog.com/entry/2019/05/06/135147
スマホアプリの設計を雑にしたのでコードを書いていく。
Clean Architecture 達人に学ぶソフトウェアの構造と設計
なんとなく読み始めた。オブジェクト指向ってなあに?についてはいままでで一番納得感がある。まだ本番に入ってない感じ。さっと読みたい。
これからやること
- 読書会プラットフォーム作る
- プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
- 読む
- ElectronかWebアプリ(サーバなし)でNature RemoのPC用クライアントを作る
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- あとはSPAとJSの学習用に
- 読書会プラットフォームの後
- あとはSPAとJSの学習用に
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- Goならわかるシステムプログラミング
- Kotlinがらみなんか
- Kotlinインアクションとか
- 英語
- 中国語
- ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
- なにがいいのかよくわからん
- Effective Go - The Go Programming Language
- パタヘネ
- スマホアプリ作る
Android Architecture Components Basic Sampleを眺める
なんとなくAndroidアプリ作れそうな空気は感じたけどどういう構造にするのが一般的なのか知りたかったのでこれを眺めている。
root
BasicAppがApplicationを実装しててこいつ経由でリポジトリとってこれるようになってる
db
- DataGenerator
- fixture的なやつ
converter
Utility的な
dao
Dao。 LiveDataで受けるようにすると、データの変更に対してXXXを発火、みたいなことができる
entity
Entity。
model
なんかデータのフィールドを持ってるinterface。entityが背負っている。 entityをmodelの層で使うぜ的なあれ?
ui
Activityがここにいる MainActivityのonCreateの引数のBundleてなんだろ
https://qiita.com/yyyske/items/c6e342a9008bebef75bd
Activityが死ぬとここになんか入ってくるらしい
Activityが破棄されたあとの復元時に必要なデータをbundleに突っ込んどいてonCreateでbundleがnullの時に復元すると良いらしい
が、このサンプルではそういうことをしてる感じがしないのでよくわからん
Adaptor
Flagmentでモデルに変更が入るとAdaptorに変更後のデータをセットする感じ RecyclerView.Adapterは多分RecyclerViewに値をバインドするのをやっている
Viewmodel
- ViewModelがいる
- ViewModelのファクトリが初期化されるタイミングでApplicationからリポジトリを取得してる
- ViewModel自体はリポジトリとApplicationを受け取って初期化時に必要なデータを取ってきてる
ということはViewModelそのものは 画面に表示するためのデータを取ってきて保持するやつ という理解でいいのかな
ViewModelはFlagmentのonActivityCreatedで生成している。 https://github.com/googlesamples/android-architecture-components/blob/17c315a050745c61ae8e79000bc0251305bd148b/BasicSample/app/src/main/java/com/example/android/persistence/ui/ProductFragment.java#L68
onActivityCreatedはFlagmentが呼び出されたActivityのonCreateで呼ばれる http://sakura-bird1.hatenablog.com/entry/20111207/1323267262
その他
fragmentってなんだ https://qiita.com/Reyurnible/items/dffd70144da213e1208b Activityの画面の中に表示される一要素って感じ
ざっくり流れとしての理解
- MainActivityが呼び出されると、Fragmentを生成して画面要素にFragmentを追加?
- FragmentのonCreateViewが呼ばれて、レイアウトが設定される
- FragmentのonActivityCreatedが呼ばれる
- ViewModelProviders経由でViewModelを生成する(ViewModelProvidersはViewModelのライフサイクルを管理してくれるらしい)
- subscribeToModelでモデルをサブスクライブする
- Daoからデータを変更すると、LiveDataで取得したデータについてオブザーブしている部分が発火する
- 変更後のデータをアダプター経由でViewに伝える
大体こんな雰囲気だと理解した
Android 入門を読んでいる
Android 入門を読んでいる
使ってた筋トレ記録アプリが突如としてサービスを終了し、他にしっくり作るアプリが見つからなかったのでとにかく単純なログアプリを作ろうとしている。 ので、とりあえずAndroid入門を読んでいる。
てきとう
- Activity:単位がよくわからない。今の所1画面1アクティビティだけど説明見た感じそういう事でもなさそう
- ユーザがなんかする1単位? * 画面でいいらしい
- AndroidManifest.xml
- ViewGroupはViewを束ねたやつ
- レイアウト、という感覚で良さそう
- Viewはレイアウト内の要素
- UIはXMLで定義する
- テキストはstrings.xmlに定義してUIのXMLで設定する
- ローカライズとかの関係のアレだと思う
- リソースはR.xxx(package).xxx(id)で参照できる
- なんでだ
ボタン押してどうこう
Activity内にメソッド定義(引数がViewで、戻り値なし)して、これをView側のonClick属性に設定すると押したタイミングでメソッドがコールされる。
IntentはコンポーネントをバインドしてXXXする、みたいなのを表現する何かっぽいが感覚がわからん。Activity内のメソッドから別のActivityをセットしたIntentを用意してstartAcitivity()するとActivityから別のActivityを起動できる感じ。 Intent経由でActivity間のメッセージ送信もできる。起動した後のActivityでもIntentを参照できるっぽい。同じインスタンスなのかよくわからん。
Android StudioでActivity作るときはNew > Activity > Empty Activity
で作るとレイアウトファイル作ってマニフェストにActivityをセットして、までをまとめてやってくれる。
コンポーネント
https://developer.android.com/guide/components/fundamentals?hl=ja
- Activity
- 画面
- Service
- バックグラウンドで動くやつ
- 再生中の曲とか
- ContentProvider
- BroadcastReceiver
- なんかイベントハンドラ的なやつ?
- 電池きれそうになったらXXXX!とかなんかダウンロード終わったら通知みたいな
- 状況に関わらずなんか起きたらなんかする、みたいな感じ?
別のアプリのアクティビティも起動できるらしい。自分で開発したアプリからデフォルトのカメラアプリを起動するとか。プロセスは別になる。 なので、Androidアプリのエントリポイントは複数あって、main()ではない。いわゆるアプリ起動時のエントリポイントはマニフェストで定義する。
なんとなく雰囲気的には
アクティビティからインテントを定義して別のコンポーネントをコール→コンポーネントが起動する。インテントでゴニョゴニョする→元のアクティビティに戻したければ戻す。インテントを介してデータを戻したりもできる
みたいな感じが基本的な流れなんだろうか
コンテンツプロバイダ
https://developer.android.com/guide/topics/providers/content-provider-basics?hl=JA
そもそもなんなのかがわからん 永続化のための抽象的なレイヤーなのかなと思ってるが
なのでチュートリアルを見ている https://developer.android.com/guide/topics/providers/content-provider-creating
と思ったけど単純にローカルのSQLite使いたいだけならRoomな感じがするな
Room
https://developer.android.com/training/data-storage/room
we highly recommend using Room instead of SQLite はい
DatabaseクラスからDaoを取ってきてDao経由でEntityを取得したり永続化したりする感じだ
適当なボタンのonClickからデータを登録したりなんだりしたらこうなった
Caused by: java.lang.RuntimeException: cannot find implementation for com.example.myfirstapp.model.AppDatabase. AppDatabase_Impl does not exist
https://stackoverflow.com/questions/46665621/android-room-persistent-appdatabase-impl-does-not-existの回答に従ってbuild.gradleをいじると
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
になった。
https://qiita.com/toastkidjp/items/49ad3035a6df525ce040 ほーーん???
ほーーん?????
ボタン押すとデータ取ってきて画面に表示、みたいのはどう実装するのが良いのか
安直にAsyncTaskで全部やるようにしたら元のスレッドからしかビューをいじれんぞと怒られる
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
DB触るだけならこれで良さそうだけど画面に表示して云々はこれだとダメそう
DB触るの重い処理だからバックグラウンドでやろうぜ、はわかるようなわからないような感じなんだけど(SPAでAPI叩くのと同じノリだと思っている)、紙芝居形式のアプリでそこ頑張るメリットがよくわからなかったのでとりあえずallowMainThreadQueriesでいいやとなってしまった 初期化はどのタイミングでするのが良いのだろうか あとはマイグレーションどうするとかかなーその辺解決したらとりあえず作り始めて良さそうだ
なんかこのチュートリアルが良さそう
Android Room with a View - Kotlin
リポジトリがDao持ってて、ViewModelインスタンスの初期化時にリポジトリ初期化してあとはViewModelがリポジトリ持ってる感じだった これActivityでも同じ事していいんだろうか というかViewModelがなんなのかよくわかってない
なんかいい感じのサイズのサンプルアプリケーションとかないかな
サンプルを眺める
良さげだ
2019年4月にやったこと
なんかKotlinのリファレンスとか見てた
Release It! 本番用ソフトウェア製品の設計とデプロイのために
17章くらいまでみた。読み終わったらどうしようかな的なことを考えている。サーキットブレーカーで遊ぶ会みたいなのやったら良いだろうか。
英語
English Bellを42レッスン受講した。ゴールデンウィークはサボっていた。ステージ7の途中まで行った。
中国語
https://www.amazon.co.jp/dp/4863922191をひたすら読んでた。
若干掴めてきた感じはある。6/23に中国語検定の準4級と4級を受けてみる。
速習 Kotlin: Javaより簡単!新Android開発言語を今すぐマスター 速習シリーズ
ざらざらっと読んだ。公式のリファレンスだけでも良さそうではあったけどサクッと読めたのでよかった。
Kotlinのリファレンス読む
読んでる
http://inabajunmr.hatenablog.com/
どこまで読むか悩んでるんだけどOtherが結構重要そうなんだよな Core Librariesとかも読みたい
OAuth徹底入門 セキュアな認可システムを適用するための原則と実践
Kindleでセールやってたので勢いで買ってしまった。電車とかで読んでる。多分release it読み終わってから真面目に読む
これからやること
- 読書会プラットフォーム作る
- プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
- 読む
- ElectronかWebアプリ(サーバなし)でNature RemoのPC用クライアントを作る
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- あとはSPAとJSの学習用に
- 読書会プラットフォームの後
- あとはSPAとJSの学習用に
- なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
- Goならわかるシステムプログラミング
- Kotlinがらみなんか
- Kotlinインアクションとか
- 英語
- 中国語
- Release It!
- ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
- なにがいいのかよくわからん
- Effective Go - The Go Programming Language
- パタヘネ
Kotlinのリファレンスを読んでいるメモ
Kotlinのリファレンスを読んでいる
諸事情でKotlinを覚えるかとなったので
速習 Kotlin: Javaより簡単!新Android開発言語を今すぐマスター 速習シリーズ
- 作者: 山田祥寛
- 出版社/メーカー: WINGSプロジェクト
- 発売日: 2018/09/26
- メディア: Kindle版
- この商品を含むブログを見る
とりあえずこれをざっと読んだけど結局リファレンスを読んでいる この本はJavaわかれば電車とかでびゃっと読めてなんとなくKotlinかけるようになると思うのでやる気あんまないけどざっくり把握したいみたいな時には良さそう try式ないとかあったのでなんとなく書くレベルで必要なのが網羅できてるかというとなんとも言えない
やる気があるならリファレンス読めば良さそう だいたいのことがそう
どこまで読んだか忘れちゃうのでメモレベルのメモ
Control Flow: if, when, for, while
- ifが式なので三項演算子ない
- if式はelseないとだめ
- when(switchみたいの)もそう
- 引数なしwhenはif-else ifのノリで使える
- else ifだらけになる場合こっちのが良さそう
Returns and Jumps
Classes and Inheritance
- プライマリコンストラクタはbodyを持てないので、initブロックで初期化処理を書く
- initブロックは複数かける。書いた順に実行される
- initブロックではプライマリコンストラクタの引数を参照できる
- プライマリコンストラクタの引数はクラスのフィールドになる
- valで宣言した引数はread-onlyなフィールドになる
fun main() { var test = Test("test") println(test.value) } class Test(var value:String){ init { println("You can read property defining at Primary Constructor. $value") } init { println("You can define multiple initializer") } }
- 全てのinitializerはセカンダリコンストラクタよりも前に実行される
- プライマリコンストラクタがないとデフォルトコンストラクタを生成される。デフォルトコンストラクタを露出せずプライマリコンストラクタを定義したくない場合、引数なしでprivateなプライマリコンストラクタを定義する
- プライマリコンストラクタの引数が全てデフォルトを持っていると、JVM上ではそのデフォルトを使う引数なしコンストラクタを生成する
- 全てのクラスはAnyを継承している
- 継承する場合は継承元のコンストラクタで初期化してあげること
open class Super(val a:Int, val b:Int) class Child1(a2:Int, b2:Int): Super(a2,b2) class Child2: Super { constructor():super(1,2) }
- オーバーライドできる要素にはopenを明示する必要がある
- overrideしたメソッドを、さらに継承したクラスでoverrideするのを防ぐ場合はfinal
open class Super { open fun method() { println("parent") } } open class Child1 :Super(){ override fun method() { super.method() println("child1") } } class Child2 :Child1(){ override fun method() { super.method() println("child2") } } fun main(args: Array<String>) { Child2().method() }
- プロパティもオーバーライドできる
- あんまり用途がわかってない
- カスタムアクセサの拡張とかだろうか🍙
- 派生クラスの初期化よりもベースクラスの初期化のが先に走る
- ベースクラスのinitializerでopenなメンバを使わない
- 派生クラスでoverrideしたメンバが初期化されてないのにinitializerで呼ばれる形になるので、予期しない動きをする可能性がある
- ベースクラスが複数あって同じメンバが存在したらオーバーライド必須
- クラスはstaticなメソッドを持てない
- トップレベル関数を定義しよう
- クラス経由で関数を呼びたいが、初期化はしない場合はオブジェクト宣言orコンパニオンオブジェクト
Properties and Fields
- backing fieldの参照はカスタムアクセサを介さない
- カスタムアクセサの中でフィールドを参照すると再帰になって死ぬ
- backing propertiesの用途がよくわからない
- lateinitをつけた変数はインスタンス生成時に初期化しなくてもコンパイルエラーにならない
- ただし、初期化せずにコールすると例外
- DIとかの文脈で使うらしい
- Setterインジェクションとか?
- Nullableでnullで初期化するより取り回しいいのかな?
interfaces
- インターフェースはプロパティをもてる
- が、abstructかカスタムアクセサの実装のみ
- backing fieldはもてないし、カスタムアクセサから触れない
- 複数のインターフェースを実装した時にシグネチャが被るメンバがあったらそいつはオーバーライドしないといけない
Visibility Modifiers
- トップレベルに関数を定義できる
- トップレベルの要素に対するVisibility Modifiers
- privateはfile内から参照、internalはモジュール内から参照できる。protectedはつけられない
- クラスのメンバに対するVisibility Modifiers
- privateはクラス内、protectedはそのクラスとサブクラスから、internalはモジュール内から参照
- モジュールはまとめてコンパイルした組み合わせのこと?🍙
Extensions
- こんな感じですでにあるクラスを拡張できる
fun String.yeah(){ println(this) println("yeah") } fun main(args: Array<String>) { "oh".yeah() }
- メンバと拡張関数のシグネチャが同じだとメンバが優先される
- ハマりそう
- Nullable型を拡張するとレシーバがNullableになる
- レシーバがnullでも呼べる
- 拡張プロパティ
- カスタムアクセサだけ
- プロパティとかフィールドとかの言葉の定義を一回整理したい🍙
- クラスのなかで他のクラスを拡張できる
- 定義したクラスの中でだけ有効っぽい
class C (val value:Int) class D { fun C.a(){ println(this.value) } fun b(c:C){ c.a() } } fun main(args: Array<String>) { D().b(C(1)) }
Data Classes
- Lombokの@Dataみたいな
- 生成されたメソッドはprimary constructorで定義したメンバしか使わない
Generics
- 型パラメータが推論できる場合は、コンストラクタ呼び出し時に省略できる
class A
fun main(args: Array
- in/outはこの記事がわかりやすかった
- inは型パラメータが引数の型にだけ使われるマーク
だったら、Tが引数の型のメソッドがある - その型パラメータが設定されたクラスのメソッドは、Tの継承クラスを渡せるはず
- outは型パラメータが戻り値の型にだけ使われるマーク
- 戻り値を、そのクラスの親としてそのまま格納できる
- ちょっとなんか怪しいのであとでもう一度🍙
Nested and Inner Classes
- ネストされたクラスにinnerがついてるとouterを参照できる
class A (val value:Int){ inner class B { fun print() { print(value) } } }
- 匿名クラスはobjectつける
interface A { fun print() } abstract class B { abstract fun print() } fun main(args: Array<String>) { val a = object : A { override fun print() { print("test") } } a.print() val b = object : B() { override fun print() { print("test") } } b.print() }
- Sam変換微妙に理解できてない🍙
- Javaの関数型インターフェースにのみ使えるっぽい
fun test(s:Comparator<Int>) { s.compare(1,2) } fun main(args: Array<String>) { test(Comparator { o1, o2 -> o2 - o1 }) test({ o1, o2 -> o2 - o1 }) // これなんでだめ? }
Enum Classes
- こんなんできる
enum class Test { A { override fun print() { println("AAAA") } }, B { override fun print() { println("BBBB") } }; abstract fun print() } fun main(args: Array<String>) { Test.A.print() Test.B.print() }
- interfaceを実装できる
- メンバはclassに定義してもいいし、enum値に定義してもいい
interface A { fun A() } interface B { fun B() } enum class E:A,B { ENUM{ override fun B() { println("BBBB") } }; override fun A() { println("AAAA") } } fun main(args: Array<String>) { E.ENUM.A() E.ENUM.B() }
Object Expressions and Declarations
- なんかの方を継承したanonymous classのインスタンス生成には、object式を使う
- object式に複数の型を渡す奴が何なのかよくわからん🍙
- 匿名オブジェクトをpublicな関数で返すと、そのオブジェクトのメンバにはアクセスできない
- クラスっぽい感じでobjectを宣言するとシングルトンになる
- スレッドセーフ
- 初期化はスレッドセーフ
- 何かのクラスを継承できる
- クラス内のオブジェクトはcompanionで宣言できる
- コンパニオンオブジェクトがあんまり理解できてない?🍙
Type aliases
- 既存の型にエイリアスをつけられる
typealias Maaaap = Map<String, Map<String, String>> fun main(args: Array<String>) { val map : Maaaap = mapOf("p" to mapOf("c" to "v")) }
- 関数型のエイリアス
typealias F = (Int) -> Int fun main(args: Array<String>) { var a:F = {a:Int -> a} }
- ネストされたクラスにも行ける
- インナークラスとネストされたクラスの違いが理解できてない🍙
- あくまでエイリアスで同様の型として扱われる
typealias Integer = String fun method(value:String) { print(value) } fun main(args: Array<String>) { val ok:Integer = "YEAH" method(ok) }
Inline classes
- こういう使い方であってるんだろうか
class Yes { fun yes(){ println("yes") } } inline class LoggingYes(val value: Yes) { fun yes(){ log.info("--- yes start ---") value.yes() log.info("--- yes end ---") } }
- 普通のクラスとの違いがよくわからない🍙
- これはパフォーマンスの話だけ?
Delegation
- byに指定したプロパティの引数をオブジェクトでインターナルに保存し、そのクラスが持っている全てのメンバをbyが指定されたクラスのメンバとして扱える
Delegated Properties
- カスタムアクセサの共通化のためにgetterとsetterを定義したクラスを作ってbyで委譲できる
- lazyにLambdaを渡すと遅延評価できる
import kotlin.reflect.KProperty class Data { var count:Int = 0 val a:String by lazy { println("compute") count++ "ohhhhhhhhhhhhhhhhhhhh" } } fun main(args: Array<String>) { val e = Data() println(e.count) // 0 println(e.a) // ここでlazyに定義したLambdaが計算される println(e.count) // 1 println(e.a) // 2回目はそのまま返す println(e.count) // 1 }
- Delegates.observableはsetterの処理を委譲
- 型と変更前、変更後の値が参照可能
import kotlin.properties.Delegates class Data { var a:String by Delegates.observable("initial"){ property, oldValue, newValue -> println("$property from $oldValue to $newValue") } } fun main(args: Array<String>) { val e = Data() e.a = "a" // var Data.a: kotlin.String from initial to a }
- vetoableはbooleanを返すラムダを定義してfalseを返すと値を更新しない
import kotlin.properties.Delegates class Data { var a:String by Delegates.vetoable("initial"){ property, oldValue, newValue -> println("$property from $oldValue to $newValue") if (newValue == "fuck") { false } else { true } } } fun main(args: Array<String>) { val e = Data() e.a = "a" println(e.a) e.a = "fuck" // この代入は無視される println(e.a) // a }
- なぜmapに委譲できるのかよくわからない 🍙
- 委譲プロパティの要件を満たしてないように見えてる
- local変数も委譲プロパティ使える
- 使い所難しい気もする
- provideDelegate理解できてない 🍙
Functions
- デフォルトの引数は継承しても引き継ぐ
open class Yes { open fun hello(value:String = "hello") { println(value) } } class Yes2: Yes() { override fun hello(value: String) { super.hello(value) println("hello2") } } fun main(args: Array<String>) { Yes2().hello(); }
- 戻り値が不要な場合、戻り値はUnitとなる
- この時の型の指定はOptional
- 1つの式だけの関数は中括弧を省略できる
fun a(a:Int, b:Int) = a * b fun main(args: Array<String>) { println(a(2, 3)) // 6 }
- 戻り値の型は推論されない
- 可変長引数はvararg
- infix function
infix fun String.join(value:String) = this + value fun main(args: Array<String>) { println("YEAH" join "OHHHHHHHHHH") }
- ローカルな関数定義ができる
- あんまり用途わかってない
fun main(args: Array<String>) { fun yes() { println("yes") } yes() }
Higher-Order Functions and Lambdas
- 関数型は関数型インターフェースじゃなくてこんな感じ
val sum1 = { x: Int, y: Int -> x + y } val sum2:(Int, Int) -> Int = { x,y -> x + y } fun main(args: Array<String>) { println(sum1.invoke(1, 2)) println(sum2.invoke(1, 2)) }
- 関数を引数にとる関数を高階関数という
fun test(text:String, func: (String) -> String){ println(text) println(func(text)) } fun main(args: Array<String>) { test("yes", {it + "func"}) // 引数が一つならitで参照できる test("yes"){it + "func"} // 関数型の引数が最後なら外に出せる }
- 無名関数だとこうなる
fun test(text:String, func: (String) -> String){ println(text) println(func(text)) } fun main(args: Array<String>) { var a = fun(a:String): String { return a + "func"; } test("yes", a) } * 外側のスコープの変数にアクセスできるし、変更もできる fun main(args: Array<String>) { var a = 1 var b = {println("b");a = 100} println(a) // 1 b() // bの関数をコール println(a) // 100 }
fun main(args: Array<String>) { val join = fun String.(arg:String): String = this + arg // レシーバ付き関数は println("yes".join(" no")) // yes no // このノリで使える }