字幕表 動画を再生する 字幕スクリプトをプリント 翻訳字幕をプリント 英語字幕をプリント ROMAIN GUY: Good morning, everyone. 皆さん おはようございます [APPLAUSE] 待って 私たちではなく Wait, don't cheer us. 次のスピーカーに拍手をお願いします Cheer the next speakers. Android Platform チーム代表 ローマン・ギーです So I'm Romain Guy, representing the Platform team on Android, それから Toolチームの トール・ノルビーです and this is Tor Norbye representing the Tools team. でも私たちが お目当てではありませんよね But you're not here for us. スペシャルゲストをお迎えしています You are here for very special speakers. ローマンと私は TOR NORBYE: Yeah, so Romain and I Kotlinの公式発表ができることを have been incredibly excited about this official 大変うれしく思います announcement of Kotlin. 実は2人とも Kotlinのファンなんですよ We both love Kotlin, in case you hadn't noticed already. これ以上スピーカーの時間を 奪いたくはありません And we don't take any more time from the speakers of honor. さあ お迎えしましょう So without further ado, here they are. 皆さん こんにちは [APPLAUSE] これはいいですね HADI HARIRI: Hello, everyone. 初めてKotlinの話をした時のことを 考えていました Aw, that's nice. 4年半ほど前のことですが So I was thinking the other day, the first time that I ever 900人収容できる会場だったのに 参加者は7人だけでした did a talk on Kotlin, it was like 4 and 1/2 years ago. ですから 今日は大勢の人が来てくれて うれしいです And they gave me a room for 900 people and 7 people showed up. ありがとうございます So it's kind of nice to see more of you show up today. 30分ほど時間があります Thank you. もっと短いかな [APPLAUSE] 28分でKotlinのツアーをします Anyway I've got roughly around 30 minutes. 言語全体のカバーはしません Actually, a little bit less. 使い方とどんな利点があるかを 28 minutes to give you a whirlwind tour of Kotlin, できるだけお見せします so I'm not going to cover the entire language. よろしいでしょうか? I'm going to try show you as much as I possibly can すべてライブコーディングで やろうと思います and how you can use it and where it provides you 失敗した場合は Google動画があります with some benefits, OK? つまり YouTubeの動画ですね So I'm going to try and do it all with live coding, それをご覧ください so if it all goes terribly wrong, there's a Google video-- 簡単なものから始めたいと思います I mean there's a YouTube video of this somewhere as well. ご覧のとおり データクラスです So you can watch that. mainファイルにいます OK, so we're going to start with something very simple データクラスで moneyという新タイプを作成して that you've already seen, data class. Int型ですね And I'm in a file called main. 今は説明しません So data class, I'm going to create a new type called money, type stringの curerncyがあります and it's going to happen amounts which is of type Int. OK? I know, don't say anything for now. 両方のプロパティで And it's going to have a currency of type string. 読み取り専用のプロパティです OK? これは皆さんおなじみだと思います And this is both properties, and they're 基本的にデータクラスです going to be read only properties. 先に作っておいた Javaと比較してみましょう So this is something that you're already familiar with. 先に作っておいた Javaと比較してみましょう It's essentially a data class. 並べてみましょう Let's go ahead and compare that to a Java one JavaMoneyをアップしてみましょう that I have done earlier. こちら側を So split vertically. Javamoneyですね And let's get the Java money up-- actually, 今書いたものと同じです let's go down this side. JavaMoneyは基本的に Java money-- so there you go. 2 getter を提供するデータクラスです That's kind of the equivalent of what I've just written, right. イミュータブルですから 読み取り専用です A JavaBean essentially, a data class このdata modifierは基本的に that provides two getters. ストリングに全体を渡します They're immutable, so they're read only. ストリングのように Kotlinではcopyと呼ぶ And this data modifier over here, what that's doing cloneを渡してくれます equalを行います is essentially giving me a whole bunch of things, hashCodeを行います like the to string, it's giving me the clone, これでいいでしょう which in Kotlin it's called copy, it's doing the equals, すばらしい でもなぜこれが必要なのでしょうか? it's doing the hashCode. それは優れたIDEは これを生成するからです Now you say, OK, well that's great. 本当です そうです Brilliant, but why do I need that? しかし問題となるのは Because any good IDE is going to generate that for me. コードを維持するときです It is true, it does. 新たなプロパティを追加するたびに戻って But the problem is that that's code you're コードを変更しなくてはなりません going to have to maintain. あなたは気が付かないけれど 他に発生するであろう問題は And every time you add a new property, そのコードがスタンダードスタッフ you're going to have to go back and change that code. そのコードが標準のもの And the other issue that you're going to have is you IDEが生成したものあるいは don't know, in fact, if that code is あなたが少しいじることもありますね the standard stuff that Kotl-- いいですか? that IDE has generated for you, or you've 最初の行を 保存するだけではないのです tweaked it a little bit. さて OK? function mainを作成します So it's not just about saving on typing on the first line. こいつは閉じましょう Right. Kotlinの上部のエントリーポイントで Now what I'm going to do is go ahead クラスとして public static void mainありますが and create a function main. Kotlinにはその必要はありません Let's close this guy over here. Kotlinではトップレベルに すべてを入れられます And this is the top entry point of Kotlin, いい意味での JavaScriptのようなものです so you have a public static void main in a class. ともかく 必要はありません You don't need that in Kotlin. 本日お見せする どの機能もすべて So in Kotlin, you can put everything in the top level. top levelに ファイルに追加していきます It's kind of like JavaScript in a good way. しかし 他にmember functionsが ないわけではありません And so you don't have to-- どんなクラスでも data classですら and I want to reiterate, every function and everything member functionがあります that I'll show you today, I'm going to just add it しかし簡潔にしたいのと in the file as a top level thing, これからお見せする目的ために but that doesn't mean that you don't have any more member top levelにおきますね functions. これからmoneyの 新しいインスタンスを作成します Anything, any class, even a data class これを例えば ticketsと呼びましょう can have member functions. Money 100で $にしますね But for brevity and for the purpose ここでは明示的な型としますが of what I'm showing you, I'm just しかし 基本的に私がやっていることは 型推論です going to put it as top level, OK? Kotlinは型推論において 強力であり So I'm going to create a new instance of money. できる限り推論してくれます We're going to call it, for example, tickets. ですから 型を明示的に 言う必要がありません And I'll say Money 100, and it's going to be dollars, right? 例えば popconeにしましょう And I'll get into the explicit type here, tickets.copy です but essentially here what I'm doing is type inference. これで基本的に So Kotlin is very strong in type inference, 直前のものとプロパティすべてを copyします and as much as it can infer, it will for you. パラメータをパスしなければ So you don't have to explicitly tell the type. これは直前と同じ値を取ります And then I'll say, for example, popcorn. 新しいパラメータを渡して Let's say tickets, copy, right? 例えばスペインでは ポップコーンは So what that's going to do is basically 映画チケットの7倍の価格です copy the previous one for me, and all of the properties. 500Euroとかね So if I don't pass any parameters in, いいですね it's going to just take the same values as it has before, OK. これで例えば So I can pass in a new parameter and say, もし tickets が popcornと 等しくなければ you know, in Spain, for example, popcorn 「they are different!」 (違うぞ!)とプリントします is seven times the price of the entry of the cinema, ここではひとつずつプロパティを 比較しています so that's going to be like 500 euros. ポイントの比較ではありません Right? ポイントの比較は triple equalですよね? And now I can do things like, for instance, JavaScriptとの違いは if tickets is not equal to popcorn, 600の異なるポジションを 記憶しなくてはなりません then println "they are different!" これはfont ligatureです So what this is doing is a property comparison one by one. そのことと混同しないでください It is not doing a point of comparison. 新たなシンボルは導入しません For point of comparisons, we have the triple equal, right? OK Different to JavaScript, there isn't これを実行すると a chart of 600 different positions you have to remember. 異なっていることがわかります And this, by the way, is font ligature, これを100にして$を入れて so don't get confused with that, we 実行すると何も出てきません didn't introduce a new symbol. 同じだからですね OK. OK? So I can go ahead and just run this, 私たちが強化している機能のひとつが and I get they are different. JavaとKotlinの相互運用です And if I change this to 100 and I put this as dollars このJava moneyがこちらにあり and I run this, it's going to say to you that nothing, そのインスタンスを作成します because they are the same. javaMoney = JavaMoney OK? これは100で$になります Now one of the features we keep boosting about JavaMoneyを実行すると is the interop between Java and Kotlin. getterはありませんね So we have this Java money one over here, 実際はあるんですが getter amountを取得し so I'm going to go ahead and create an instance of it. しかし getAmountを書くと それをcompleteして I'll say javaMoney equals javaMoney, and it will be 100 IDEはプロパティ用に 置き換えます and it'll be dollars. それはgetterやsetterがないため And then if I do javaMoney, you can see プロパティのみだからです that I don't have any getters. JavaをKotlinから コンシュームする場合です Well, I do have, actually, a getter, so I can do get amount, Javaに行くと but if I write getAmount, complete it, public statics void mainを 作成し the IDE's already going to replace that for property, それから because we don't have really like getters and setters, typeを宣言します we just have properties. Money=new money 100 So that's consuming Java from Kotlin. そして$ And if I go over to the Java over here, and let's OK go ahead and create a public statics void main, これは別の物です and I'll do-- セミコロンは Kotlinではオプショナルです so let's see, I've got to declare the type. これらがオプショナルである理由は Money equals new money, 100, and dollars, and-- これらを使うべきか否か OK. きりのない議論ができるからです That's the other thing. JavaScriptで競争してます Semicolons in Kotlin are optional. money.getAmount.でした And the reason they're optional is JavaからKotlinタイプを 使っています so that you can have endless arguments over getterとsetterを取得しています whether you should use them or not. イディオマティックは使い方によります We are trying to compete with JavaScript there. 異なるJavaファイル 異なるKotlinファイルが OK, so money.getAmount. シングルプロジェクトで問題なく シームレスに作動しています So now I'm using a Java type-- sorry, a Kotlin type from Java, いくつかfunctionを作成しましょう so I'm getting the getters and the setters, right? sendPaymentというfunctionを 設定します So idiomatic depending on how you are using it. これにはmoney And that's just different Java files, different Kotlin files Moneyを取得し printIn money outします in a single project, working seamlessly without any issues. もちろん string interpolationがあるので Right, so now let's go ahead and create some functions. sending money.amountと 言えます So I'm going to create a function called sendPayment. パスをするのが シングルプロパティならば That takes a money-- 中括弧は不要です and Money-- and it's going to println the money out. ご覧いただいたとおりです And of course we have string interpolation, さてこれをコールします 例えば so I could say, sending money.amount. sendPayment tickets ですね? And you don't have to put these curly braces if it's just Kotlinでは あることに気づきます a single property that you're passing in, return typeを 定義していません as we'll just see in a moment. デフォルトではunit voidの一種ですが So now I can call this and say, for example, そうではありません sendPayment, tickets, right? 実はobjectで 基本的にシングルトンです Now Kotlin, we also have-- オブジェクトの シングルインスタンスです notice one thing here, I'm not defining the return type. これがunitならば 入れる必要はありません By default it's unit, which is kind of like void, 新たなパラメータを追加します but it's not. 例えばmessageで It's actually a object which is essentially a singleton, これはstringです a single instance of an object. デフォルトパラメーターを 持つことができます And if it is a unit, you don't have to put it there, right? ここで気づくのが コンピレーションエラーがないことで So I'm going to add a new parameter here デフォルトパラメーターにしているからです and I'm going to say, for example, with message. これでoverloaded functionで 時間が大幅に節約できます And this is gone to have string, and you overloaded member functionですね can have default parameters. デフォルトパラメータがあり So here, notice that there's no compilation error because I やりたいことができます made a default parameter. 複数のデフォルトパラメータが作れます This saves you a lot in times of overloaded function, 複数のデフォルトパラメータがあるので overloaded member functions, right? パスインしたいものを 変更できます I can just have default parameters パラメータに名前もつけられます and then do what I want. 実際 message = "Good luck!" And you can have multiple default parameters. そして money = ticketsです And since you can have multiple default parameters これも便利ですよ and you can alternate which one you want to pass in, 例えばレガシーコードを 使っている場合 you can also do names parameters. 機能の一部は修正できず 600パラメータがあり So, in fact, I could say message equals "Good luck!" そのうちの500は 真偽のブーリアン型だったりした場合 and money equals tickets. どんなパラメータが どのポジションで And this is kind of useful as well when you are using-- パスインされているか 推測できます you're talking to legacy code, for example, some いいですね function that you can't modify, and it's got 600 parameters, 皆さん Crap(ヒドイ)ですね and they're probably 500 of them are true and false Booleans, いや拍手{Clap) ありがとう it kind of gives you some insight into what parameters 自分自身で考えてみると なんてこと言ったんだって I'm passing in in every position. 気を取り直して進めましょう Oh yeah. 親の監督みたいに 編集してほしいな I love it when people crap-- よし clap. Kotlinの他のものは [LAUGHTER] とても簡単な機能があります And I'm thinking to myself, well this is going well. シングルバリューを返すような Anyway, right, let's go. single expression functionです Edit that out, like adult supervision. return typeを 消しました Right. 中括弧を消して 必要な実際の機能だけを返します One other thing with Kotlin is that when OK? we have functions that are really, really easy, この表現のコンセプトは like essentially returning a single value, Kotlinの多くの場所にあります you can just do single expression functions. インスタンスでは 他の機能を作成して So I omit the return type explicitly, convertToDollarsをコールし I omit the curly braces, and I just return the actual function これでmoneyを取得します that I want to do. MoneyでMoneyを返します OK? ここで行うことは So, in fact, the concept of expression ステートメントで これは基本的にcaseです comes in many places in Kotlin. money_currencyが $のときは So for instance, let's create another function return moneyをそのまま行います that's called convert ToDollars. convertToDollars, それ以外必要がないからです and this is going to take a money. EURの場合は returnで Money, and it's going to return Money. money.amount timesを 実行し And then what we're going to do here 失礼 新たなインスタンスを作成します is a when statement, so that's essentially case, right. money.amount ・BigDecimal So when money_currency is dollars, 1.10 こうすると$になります then we'll do return money as is, right, because I 或いは IllegalArgumentException don't need to do anything. "not the currency you're interested in!" And if it's EUR, then what I'm going to do is return, これをexpressionとして 扱うことができます we're going to do money.amount times-- このretunを外して sorry, I've got to create a new instance. ここに入れて Money, and then it's going to be money.amount times BigDecimal expressionを 返すようにします 1.10, and then that's going to be dollars. ここのreturnも外すこともできます And else, throw IllegalArgumentException, ここのMoneyを外して ここも外して "not the currency you're interested in!" single expressionを得られます So this you can actually treat a when as an expression. OK? So I can remove this return over here, remove this return over Single expression functionです here, put it just here, and then this just ここで気づいたことがあるでしょう makes the when always return an expression. エラーが出ました And in fact, you can even remove the return here, なぜならBigDecimal を intで 運用しようとしたため remove the Money here, and remove that there, refactorとして and you get a single expression. BigDecimalと呼びます OK? BigDecimalといえば Single expression function. BigDecimal BigDecimal Now one thing that you notice here 100 そしてBigDecimal that this is giving me an error because this is-- BigDecimalとタイプするのは 楽しいです I'm trying to operate a BigDecimal with an int, いいですね so we're going to go and refactor this, これでできました and we're going to call it BigDecimal, OK. BigDecimalを見ていくと Now talking about BigDecimal, oh, here we go. 新しいBigDecimalを作成し bd1とし BigDecimal, BigDecimal 100 and BigDecimal-- bd1=BigDecimal 100 I love typing BigDecimal. bd1には割り算や掛け算などの I love it. たくさんのfunctionあるのがわかります So we've got this over here. percentはどうするか? Now if you look at, actually, BigDecimal-- BigDecimalのパーセントが知りたい so if I create a new BigDecimal, we'll call it bd1 通常ならば あなたは基本的に equals BigDecimal 100. 独自のバージョンを作成し You can see the bd1 gives me a whole bunch of functions Kotlinでは like divide, multiply, all of these things. 私たちが追加した機能は What if I wanted to do something like a percent? C#に詳しければ I wanted a percentage of BigDecimal. extension functionと 呼ばれます Now normally you would, basically, これはどのクラスやタイプも使え 拡張できます inherit from that and then create your own version BigDecimalの機能を取得します and have all of these things, but in Kotlin, 拡張したいクラスに命名し one of the features that we've added-- パーセントとします and if you're familiar with C#-- パーセントとしてほしいのは is called extension functions, which essentially 例えば integerがいいでしょう means that you can take any class, any type, and extend it. 見てみましょう So I can take a function of BigDecimal, これは拡張機能で I put the name of the class that I want to extend, classやobejectの インスタンスがあります and I say I want to do a percent. これを参照して使用できます And what is the percentage that I percentageでmultiplied want to do, for example, an integer, and then it would be, big decimalでラップされます let's see. ここでも So given that this is an extension function, percentage it's going to have an instance of that class, of that object, divideして right. またBigDecimal 100です So I can use that, reference that with this. これはpercentageのはずです And I say this multiplied by the percentage-- percentageです いいですね and then this has got to to be wrapped in a big decimal bd1で起きたことは percentage again-- ですよね? percentage. percent 7 で And then that divide-- これで 7percentが得られます and then another BigDecimal 100. パッケージで定義されたところで And what's wrong with this, that should be percentage. その拡張機能が含まれます So percent-- age. このケースの場合 com.jetbrains.gioにあります OK, so now what happens is that on bd1, I have percentage. そこに含まれます OK. 拡張機能を作成できます And I could do percent 7, and that would give me standard libraryは a certain percent. 一連の拡張機能で成立しています And that extension function gets included anywhere where さらに一歩進めましょう it is defined in the package. すべて拡張したからです So here in this case, I have it in com.jetbrains.gio integerを拡張しましょう and that will get included there. fun Int So you can create extension functions, percentOfで reverseできます and we'll see that the standard library actually 何かの10 % consists of a whole bunch of extension functions. money 例えば moneyの10%にしましょう Now we'll take this one step further, これが返すのは because I can actually extend everything. moneyを返します So let's go ahead and extend an integer. amount.multiplyで So I'll say fun Int. 実際にインスタンスを参照して percentOf and here will do the reverse. 再び BigDecimalで ラップすることが必要です So I want like 10 percent of something, right. 100で割ります So I'll say money, for instance, I want 10 percent of money. OK And that's going to return the-- 正しい順序だと思います let's see, it's going to return money. 実装が間違っていても 構いません Then it will be amount.multiply and then here it's going 大丈夫です to reference the actual instance, so it will be this-- そしてここでできることは and again, this has to be wrapped in BigDecimal, 7.percentOf and then divide by 100. {BigDecimal 100) OK. OK? And I think I got that in the right order. 違った If the implementation is wrong, doesn't matter. Moneyです Who cares. Money 拍手はまだですよ Anyway, so now what I can do is something like this. Money Seven percentOf BigDecimal 100. moneyを OK? 7.percentOf popcorn Oh no, sorry. いかがですか? Money. もっとよくしましょう So I can do Money-- no, don't clap yet. 私がしたいのは こういったことです Money. 7 percentOf popcorn Oh, let's just take the money I have. これはいいでしょう 7.percentOf(popcorn). これができます OK, nice? 波が出ましたね Let's do a little bit nicer. くねくねかな? What I want to do is, in fact, something like this. Alt Enterで "infix"を加えると I want to do 7 percentOf popcorn. これでいいです That would be nice. これであらゆるシングルパラメータの 拡張機能は And you can actually do that. infix notationでコールできます You see that little wiggly there? 私がしたことは基本的に Squiggly? こちらにinfixの追加です Alt, Enter, add 'infix'. こういったことは There you go. KotlinでDSLアプローチ全体を OK so any extension function that has a single parameter 作成します can be called an infix notation. はい And what I've done is essentially add 私がひとつ気に入らないのは BigDecimalです the infix over there. うんざりします And this is some of the things that Kotlinではtype longの 値を作成します allow you know, with Kotlin, to kind of create the whole DSL long 100Lそして type longになります approach to things. また bd2= 100BDで できればいいですが Right. これはできません So one thing that I hated doing here is all of this BigDecimal. ビルトインしていないんです That's a pain. Kotlinでは拡張プロパティといいます And in Kotlin, when you want to create a value of type long, プロパティを拡張する以外は you can say long 100L, and that will be of type long. 拡張機能と同じです And it would be awesome if I could ですから bd.でできますね do like, bd2 equals 100BD, but you can't, and we これで言ってきましたよ don't have that built in. type integer上に拡張プロパティを But what we do have in Kotlin is called extension properties. 作成しますか? So they're exactly like extension functions, はい except they extend with properties. これでBigDecimalを返します So I could do something like .bd, right? そしてここで And now-- or let's, so now-- BigDecimalを返す see, it even says, do you want to create an extension property これがインスタンスです on type integer? これをexpressionを変えて Yes. もっと簡単にできます So this is going to return a BigDecimal. いってみましょう And then here, I'm going to do return BigDecimal, and this, 100.bd.です which is the instance. BigDecimalよりよさそうですね And I can, in fact, convert this to an expression 100.bd.でいいのです to make it easier. OK? So there you go. こう1つ 機能でできることは Now I have 100.bd. 拡張できるオペレータがあることです So when I'm passing that in, it looks plus operatorを拡張できます much nicer than BigDecimal, I could just do 100.bd. これをタイプしないのです OK? これのおかげで And one other thing around functions that you can do ちょっといいことがありました is, there are certain operators that you can extend. タイプが速いでしょう? So you can extend, for example, the plus operator. 今やったのは基本的に plus operatorを And what I'm going to do is I'm not going to type this out, moneyへのオーバーライドです I've just got a nice little thing これで costs = tickets plus popcornですね that has done that for me. これで金額を追加できます See how fast I am at typing? plus minus multiply できます So what I've essentially done is now override ビルトイン変換のおかげで the plus operator for money. これが可能なんです So now I can say costs equals tickets plus popcorn, right. OK And that allows me to add to monetary amounts. ここで一連のtypeを作成しています OK, you could do that with plus, minus, multiply. これはすべて消してしまいます A bunch of built-in conventions that you 一連のtypeを作成しました can follow for certain operators that allow you to do that. 作成したtypeは OK. 私はtypeを特定してなくても できるんです So we've been creating a whole bunch of types here. 例えばできることは val train の料金は And let me go ahead and delete all the stuff so we can focus. 例えば trainisはMoneyのタイプとして We've been creating a bunch of types here. それを初期化し 新たな値にしましょう Notice that in any of these types that I've created, 100.bd, そしてdollarsです I've never actually specified the type, and you can. さて先に進んで train=null So I can do, for instance, val train costs, エラーになります for example, train is of type Money エラーは2つです and then initialize it to some new value, right. ひとつはイミュータブルの 変数だからです 100.bd, and then dollars. 修正しましょう Now if I go ahead and do train=null, これえをミュータブルにします it's going to give me an error. IDEが下線を引きました And it's going to give me actually two errors. これで避けるべきところを One of them is because that's immutable variable. 指摘しています So I can fix that. Kotlinではイミュータブビリティを 強制しませんが I've now made this mutable. これをお勧めします You see that the IDE underlines it, リストと同じように so it wants to point it out that this is really something デフォルトではイミュータブルです you're going to shy away from. Kotlinでは nullはアサインできません We don't enforce immutability in Kotlin, Kotlinはnull pointerを 削除するからです but we kind of do recommend it. デフォルトではtypeは nullにできません Like all of the lists and all of these どんな理由であれ things are immutable by default. typeをnullに できるようにしたい時があります So I can't assign null in Kotlin because Kotlin うんざりしますね tries to get rid of the null pointer exception question markを追加して by saying that types aren't nullible by default, right. このタイプに nullをアサインできます But there are times when you want 通常Kotlinで作業するときは to have a type that is nullable for whatever reason, これは望まないでしょう you're bored. しないと思いますが And you can add a question mark, and then that しかし Javaとインターロップします Javaはnullにできます will give you the ability to assign null to that type. functionを作成するとしたら Now normally when you're working with Kotlin, 例えばfun javaMoney you probably don't want to do this. これは JavaMoneyのmoneyのタイプを取得し You probably don't want to have nullable types, これでいろいろ行います but since we're interopping with Java, Java can be null. では例えばprintlnで So if I create a function here that is, for instance, money.amountは'in valid'とすると fun javaMoney, and that takes money of type JavaMoney これはnullになります and does whatever with it. インスタンスでコールされ So let's say I do println money.amount is valid. 例えばfunctionがこのtypeを返し So this can be null. nullです It could, if it's called by an instance question markを 追加して示せます that a function that, for example, is returning これを行うと IDEがエラーを返すのが this type, it could be null. わかります And you can indicate that by adding the question mark. safe operatorsか double exclamation markだけが When you do that, you can see that the IDE 有効だと言っています これは基本的に is going to give you error. null reference exceptionだったのです It says only safe operators, or the double exclamation mark この解決法は2つです are valid here, because it's essentially まず例えば moneyはnullでないとし saying you're going to run into a null reference exception. nullでなければ 先に進んでオペレーションを行う So there's two ways you can solve this. これを上に移動しましょう First of all, you can say, for example, money, not null. OK And then do a if not null, then go ahead and operate with it. これが1つの方法です Put this one upstairs in there. 短い方法は safe operatorか OK. Elvis operatorを使うことです ここにあります That's one way. moneyがnullでなければ 何かを実行します Or the shorter way is just to use the safe operator or Elvis 楽しみたいならこれもできます operator, which is over here. これはnullだと知っているけど So now we just say if money is not null, then do something. やってみるとします Now if you want to have fun, you can also do that. OK? And that says, I know it's null, but I want ここで注意してください to shoot myself in the foot. Kotlinを始めた人は OK? ここでちょっとしたくねくねがあります And you've got to be careful with that, 本当にnullになるかどうか わからないけど because a lot of times when people start with Kotlin, nullにしたいわけではないから they get all of this little squigglies over here, ですからインスタンスがnullのケースは 扱わないとして and they're like, well I actually ただ実行したとすると don't know if it's going to be null because I really アプリを起動して待つと want it to not being null. KotlinにはNullReferenceExceptionが 除かれたはずだったのにということなります So I'm not going to handle the case where it's not null, はい so I'll just do that. さて And then they run the app and they're like, wait a minute, 他にはそうですね you set Kotlin got rid of null reference exceptions. 他のものに切り替えましょう Yes. high order functionは おなじみですね OK. これは基本的にfuntionを取ったり 返したりする機能です What else. これがKotlinにあります Right. そこで findEmails users List <Users> So let's switch to some other stuff, そして新機能を作成します like higher order functions. ここでpredicateは Now you're all familiar with a high order function, which stringを取り Booleanを返します is basically a function that takes a function OK? or returns a function, and we have those in Kotlin. これでユーザーのリストを返すでしょう So we can say findEmails users List of User, 基本的に私がやっていることは and then I'll create a new function, which is a predicate. ユーザーのリストのフィルタリングです So I'm passing in a function here, right, そうですね a function that takes a string and returns a Boolean. これは後でやりましょう OK? TODO{”Later!") And then this probably is going to return a list of users. OK So essentially what I'm doing is I'm このTODOはビルトインです filtering on a list of users. not implemented exceptionの 代わりに使えます Right. non implemented errorは So I'll do this later. これは追加事項ですが ここでは触れません To do later. KotlinではNothingは良いですが OK. ここでは触れません This to do, by the way, is built in. 気にしなくて大丈夫です You can use it instead of not implemented exception-- 私の戯言です non implemented error. OK And it does a additional thing that we won't get into, どうもありがとう but nothing is actually very nice in Kotlin, これをどう使うのでしょうか? but we won't cover that now. findEmailsを行い It's nothing to worry about. 実際にuserがいるので userを作成しましょう I just made that up. usersFromJSONFileです OK. users.json OK, thank you. 私が用意した機能です So now how do I use this? 基本的にjsonを使ってファイルから userを読みます I can do findEmails, right, and I'll say-- 典型的なdata classで I actually have a user, let's create some users here. ここで目新しいことは So usersFromJSONFile. プロパティの役割りのある enum classです And I have some uses over here, so users.json. OK? So this is actually a function that I have ready, これでuserなどで which is basically using json to read some users from a file. この機能を渡します And this is a typical data classs Kotlin の Kotlin referenceを 使って that you've already seen, the only new thing name functionでパスすることもでき here is that this also got an enum class with a property 或いは lambdaでパスできます Role. Kotlinでは lambaは このシンタックスに従います OK? parameter nameをパスし そして例えば So now I can do like users, and then I'll parameter nameは .com で終わるものとします pass in that function. これで.comで終わるユーザーの リストが得られます Now I can pass in the name function Kotlinのシングルパラメーターとなり by using the column column reference, 実際に明示的な言及を省略できます or a can pass in a lambda. これを"it"に置き換えられます And in Kotlin, lambda follows this syntax. Groovyに似ています You pass in the parameter name, and then you say, for example, Kotlinで可能なもう1つのことは the parameter name ends with right .com. functionへの最終パラメータが 他のfunctionの場合 So I'm getting a list of users that end with .com. かっこに含めることができません Now when you have a single parameter in Kotlin, 使ってみると外側のようです you can actually omit having to explicitly mention そしてここでまた 特性のひとつとして it and replace it with it. これでスッキリとしたDSLを 作ることができるのです So similar to Groovy, you can just use it. これを複数行でもできます The other thing that you can doing in Kotlin 今 findEmailsを見ると is when the last parameter to a function is another function, 言語の一環のように思えますが you can actually not include it in the brackets. そうではなくfunctionなのです So it feels a little bit like it's outside. 非同期型プログラムを コローチンで実装すると And this is, again, one of the characteristics that 私たちは allow us to create nice DSLs, and you can even C#におなじみなら C#は同期するか待ち do this like multi-line. 言語でキーワードがあります So if you look at findEmails now, in a sense Kotlinにはありません it could actually feel like it's part of the language, 基本的にfunctionだけです but it isn't, it's actually a function. これでフレキシビリティが得られ And when we implemented aasynchronous programming with 別のことで何をやりたいか決定できます coroutines, we didn't like-- you know, すべて行う必要はありません if you're familiar with C#, C# does their sync or wait, すべてビルトインされています there are keywords in the language. ですから例えば dotComUsersと言えば In Kotlin, there are not, they're user.filterとして これを書き終えていくと essentially just functions. パラメーター外のバージョン So that gives you the flexibility 選択しています of deciding how you want to do different things. email.endsWith .com Now you don't have to do all of these things, そしてsortBy{it.id}とします because all of these things are built-in. 先に進んで 例えば So, for example, if I say dotComUsers, それをit.email and it.usernameに I say users.filter, and you can see that as I complete this, マップします it actually opts for the version of including out OK? of the parameter. これらの機能は実は small standard libraryに So I can say the email.endsWith .com. ビルトインされています And then I can go and sort by it.id. Androidで問題ないでしょう And then let's go ahead and do, for example, 小さいです map that to a pair of it.email and it.username. 基本的にすべて 拡張機能は OK? top of collections generic collectionsです So all of these functions are actually これらの機能はすべて built in in that small standard library 最近の流行ですね that ships, that you're not going to problems on Android, 明らかにpairを与え it's very small. それよりもいいことに And they're all in, essentially, extension functions pairを実行します on top of collections, generic collections. emailをusernameにmapします So you have all of those functional things that 何だと思いますか? are very in fashion these days. pairを作成する infix functionです And so this obviously gives you a pair, OK? and in fact, you can do this even nicer, if instead 全部のmapをせずに of doing pair, it, to. 例えば シングルエレメントだけでいい場合には So a map, email, to username. クラスを分解することもできます And guess what it is? Kotlinのデータクラスでは It's just an infix function that creates a pair. ですからid.username.emailとし OK.? idだけを使用できます Now sometimes I don't go through the whole map. 素晴らしいですが IEDから苦情が来ます I just want to, for example, say get back a single element. この変数を使ったことがないと 言っています And what you can also do is destructure classes, この場合は data classes in Kotlin. underscoreで置き換えられます So I could do something like id, username, and email. これでいいです OK and then I can just use the ID. 任意のバリューを分解できます And this is great, but then the IDE complains and says, 使いたくないものはunderscoreで well this variable is never used. 置き換えられます In that case, you can actually replace よし that with an underscore. 他には何をお見せしましょうか? So there you go. OK And you can destructure the values you want. 他のコードがあります Anything that you don't want to use, replace with an underscore algebraic data typeの 概念に慣れているなら and you're good to go. これは基本的に Booleanなどの Right. 一種のタイプです So what else can I show you? Kotlinでは コクラスの方法です OK. それの前に So I've got some other code here. 開きましょう If you're familiar with the concept of algebraic data 最初に気づくことは types, it's essentially a type that user resultに エラーがあることです can be of one type or another, like for instance a Boolean. Kotlinのデフォルトでは classから Now in Kotlin, the way that we do that is with coclasses. 引き継げません But before I get into that, let me どのclassも基本的に最終です go ahead and do an open here. classから引き継ぎたいなら Notice the first thing here, that user result open modifierを使います is giving me an error. sealedを使いました Because by default in Kotlin, you cannot inherit from sealedは基本的に classes. user result のヒエラルキーだと 言っています So all classes are essentially final. user result から引き継がれる If you want to inherit from classes, 他のクラスはどこにもありません you have to use the open modifier, right? user result から引き継がれるすべては Now I've used the sealed, and the sealed 同じファイルにあるか is essentially saying that this is the hierarchy 或いはこれらをsubclassにしても いいですが that user result has. こちらに移動して これはサブクラスにして Like, there's not going to be any other class でもこの場合はuser result で プリフィックスする必要があります anywhere that is going to inherit from user result. OK Everything that's going to inherit from user result これを外の classとして作成しました has to be in the same file, or you can make these, of course, これはなぜ行うのでしょうか? subclasses. 見た目がいいからです So I could move this up there and this would be a subclass, まさか but then I would have to prefix it with user result. これが優れているわけは 何か行うと OK. よくあることは Now I've just created it as a class outside, これが成功したら So why would I want to do this? 値を返したい Because it looks good. nullだった場合 messageにパスします No. そしてそれが成功したら Well, this is actually good because when you're 返したい値を含む このタイプが得られます doing some things, it's often like your invoking a function メッセージが含まれた 返したいタイプが and you're like, OK, well if it's successful, 得られたりすると I want it to return a value. どのプロパティのセマンティクスが エラーの状況に適用されたか If it's null, I'm going to pass in a message. どれがエラーでない状況に適用されたかを 調べるか必要があり And then you get this type that contains the values that you 或いは単にexceptionを 投げることもできます want to return when it's successful, この場合は機能を使って it contains the types that you want to return when there's 基本的に2タイプを返します a message, and then you've got to figure out この結果に基づき 別のことを行います the semantics of which properties are applied 例えば to an error situation, which properties are applied instant valを作成して to non-error situation, or you can just throw an exception. result = userresult In this case, you can use a function that 失礼 retrieveUsersです basically returns two types. when result is Success And then based on the result, do different things. そして例えば So here I say, for instance, when-- 結果を得て let's create an instant val, result equals userresult-- users forEach sorry, retrieveusers. その名をprintln します So now I can do when result is success, OK? then we're going to do, for instance, well we're usernameです going to get the result, and then 失敗した場合 we're going to do users forEach println the name. 結果は println result.message. OK? いいでしょうか? username. これで結果に基づいて And then we're going to do a failure. 返されたtypeに基づいて 別のことができます Result println result.message. ここで何かが緑になったことに 気づきました OK? 大画面で見えるか分かりませんが So now based on the result, based 緑になっています on the type that is returned to me, I can do different things. Smart castです I notice one thing over here, that this has gone green. Kotlinの機能です I don't know if you see it on the big screen, null checkを行っているとき but this has gone green. nullでなければ Smart castingですから And this is a Smart cast. 明示的にする必要はありません So that's another thing that we have in Kotlin, これはsuccess typeですから 先に進んで and you saw that when I was doing the null check, type successにキャストして プロパティにアクセスします that is said this is not null, because it is Smart casting. コンパイラがやってくれます So you don't have to explicitly come over here again and say, これがSmart castingです oh, I know that this is of type success, let me go ahead はい and cast this to type success, to then access the property. 最後にアンドレイに引き継ぐ前に The compiler will do that for you, that's filter mapについて what the smart casting is. ちょっと触れておきましょう Right. これは基本的に eager evaluationです And last but not least, before hand it off to Andrey lazy evaluationも可能です quickly just mention, also, that a lot of the things you've 例えば generateSequenceを行い been seeing with the filter map, all of those things, 例えば 1 those are essentially eager evaluation. そしてここで But we also have the ability to do lazy evaluation. it * 10を行います So I can do val, for example, sorry, generateSequence, そしてvalues.take(10) and then have something, for instance, 1. そしてforEach {println)します And then here, we'll do it times 10, and then we'll do values. 基本的にシーケンスを作成し Now I'll say values.take(10), and then forEach println it. ジェネレーターはinfiniteです Now this is essentially creating a sequence, これは停止しません a generator that is infinite. 1から始めて10を掛けます It's never going to stop. 10 elementを取得し It's going to start at one and multiply by 10. それをプリントします But what I'm saying here is that I just want to take 10 elements 10になるまで基本的に コンシュームします and then print them out. 書き出します 消しましょう And what it will do is basically consume that until it hits 10. きれいなクリスマスツリーを プリントします It prints out-- go away-- 片側だけですね it prints out a beautiful Christmas tree じゃあピラミッドかな ここで停止します that's one-sided. 何でも例えば OK, pyramid, whatever, and stops there. 私たちのusers Jasonからのusers And anything that you have, like for example, users.json the users that we had, users from Jason, users.json, asSequenceと lazy evaluationに変換しましょう you can say asSequence and convert it into lazy evaluation 同じようにです as well. これですべてご覧いただきました OK? 言語にはまだまだあります That's all we have the time to show you today. オンラインで学ぶことができます Obviously, there's way more to the language. ありがとうございました Go online, learn everything about it, アンドレイに引き継ぎます and thank you very much. ありがとう ハディ And I'll hand it off to Andrey. 皆さん ANDRY BRESLAV: Thank you, Hadi. Kotlinには既にいろいろあります Hello, everybody. 皆さんが既存の機能を習得する前に 私は意地悪くも So as you've seen Kotlin already has many things in store, 新たな機能を追加しました but I am the nasty person who adds new futures before you お話ししますが learn the existing ones. リモコンがいるな So I'll be tell you stories now, but I'll リモコンは? need to find a clicker. ないか Do I have a clicker? リモコンなしで話します No, OK. 私の役目は皆さんに OK, so I'll be telling stories without a clicker. 今後のKotlinのバージョンについて 知っていただくことです So my job here is to tell you about what ありがとう we're going to have in the future versions of Kotlin-- まず作業しているのは oh, thank you very much. 異なるプラットホームを サポートするプラットフォームです And the first big thing we're working on now KotlinはJVMbytecodeを コンパイルします is platforms, supporting different platforms. Javaプログラミング言語と同様に So historically, Kotlin compiles to JVM bytecode, デスクトップでサーバーを実行し same as the Java programming language. そしてもちろん Androidでもです So we can run a server on the desktop 同じbytecodeで and of course on Android. 古いバージョンのAndroidでも And it's just the same bytecode everywhere, 新しいバージョンでも実行できます this is why we can run old versions of Android 話はここで終わりません as well as new ones. 新たなプラットホームを追加したので But the story doesn't end there, because we そして最近私たちは are adding new platforms. 神様はプラットホームを好みませんが And recently, we've added-- JavaScriptを追加しました but God doesn't like platforms-- つまり KotlinはJavaScriptコードを ブラウザや node.jsで recently we added JavaScript, which コンパイルできます means Kotlin can now compile to JavaScript code and run これで3種の主なバーチャルマシンを サポートしています in the browser or on node.js. JVM Android Dalvik そして JavaScript VMですね So now we support three, major, very popular virtual machines, バーチャルマシンは実用的でなく JVM, Android Dalvik, and JavaScript VMs. 入手も難しい ユースケースが多くあります But there are many US cases where 例えば iOSの場合 a virtual machine is not practical or is simply バーチャルマシンは かなり限定されます unavailable. dynamic code generationは できませんし For example, for iOS, virtual machines 小さな埋め込み型システムだと VMはフィットしません are severely restricted. 例えば Linux のコマンドライン ツールには You can't do dynamic code generation, VMは長い開始ツールになります or for a small embedded system, a VM doesn't fit in. これでは実用できません Or for, say, a Linux command line tool, だからKotlin/Nativeというものを 作っています the VM will be a starting tool for too long. 現在テクノロジープレビューとして 入手可能です So it's a no go there, and that's こちらで LVMを使用して Kotlinをnative codeに why we're working on something called Kotlin/Native, コンパイルし 独立したバイナリとして it's currently available as a technology preview. 異なるプラットフォームで実行できます And there, we basically use LVM to compile Kotlin down 現在 iOS Linux Macでサポートされており to a native code, to stand along binaries that そして Windowsへの サポートを今作業中です can run on different platforms. Kotlinの将来へのビジョンは Currently, we support iOS, Linux, and Mac, お好みのプラットフォームで and Windows is in the works. モダンアプリケーション内部の 各コンポーネントで実行できることです So this is taking us to this vision with Kotlin, サーバーとクライアントが ともにKotlinで書かれた when it can run inside every component フルスタックの ウェブアプリを考えてみましょう of a modern application, on any platform you like. 或いは例えば AndriodとiOSのような So think full stack web applications モバイルプラットフォーム間の reuse codeを考えてみましょう with the server and the client both written in Kotlin, あるいは2つのユースケースを ミックスすることで or think reuse code between mobile platforms, Android 実際のマルチプラットホームを得るなど and iOS for example. Kotlinのビジョンは Or mix the two previous use cases 同じプロジェクトで 異なるモデルをもつように and get like a real multiplatform scenario. 異なるプラットフォームに コンパイルされる So our vision for Kotlin is having もちろん コードを共有したいですよね? different models in the same project 多くの物をサポートすると compile to a different platforms. 同じコードを別の場所で 実行したいですから And of course, you we want to share code there, right? 私たちはそれを 実現しようとしています Because if you support so many different things, 重要なことがあります you want to run the same code in different places. それはかつて 数多くのプロジェクトで And we're working on making that possible. プラットフォームを 一体化しようとしてきていますが But there is a very important thing, そしてたいてい 最小共通因子となってしまいます because previously, many projects すべてのプラットフォームで 使用できるものだけを取ると tried to unify platforms. 基本的に最小限の インターフェースで逗まってしまい And this often ends up being like the least common それは私たちが望むものではありません denominator, when you take only things that だから私たちは すべての最新版のAndroidなどの are available on all platforms, you are basically 特定のプラットフォームで 使用できるようにしたいです stuck with a minimal interface, and that's something コードの一部を共有したい場合のみ we don't want to have there. 共通APIを使うようにします So we want you to be able to use all 共通モデルには数多くの ビジネスロジックなどがあり the platform-specific fancy APIs like the newest これはKotlinで書かれた version of Android or something else as much as you like. プラットフォーム特定のモデルでも 並列して機能します And if you want to share some code, この2つはお互いに会話できます only then you have to resort to some common APIs. 必要なら platform APIを利用して So the idea there is that you have a common model with lots 必要なら Kotlinコードを使用します of business logic and stuff, and it can work side by side 私たちの未来は マルチプラットフォームです with a platform specific model written also in Kotlin, 次に and those two can talk to each other. 次の話題はコルーチンです So when you need, you leverage the platform API, 非常にわかりやすいです and when you need, you use the Kotlin code. 誰もが非同期コードを書きたいですよね? So take away here, our future is multiplatform. シーケンス実行するには 世界が広すぎるから Next-- oh. それが現実というものです Next big thing is couroutines. 非同期コードを書いた人は? So the rationale there is pretty straightforward, かなりの大人数です everybody needs to write asynchronous code, right? 書いたことのない人も すぐに書くことになるでしょう Because the world is too big now for sequential execution. 問題はシーケンシャルコードを書くのは And it's our reality, but it's hard, right? 難しいことです Who has written asynchronous code? 特に言語がこれを補助することを 学ぶ前は難しかったです Quite so many hands. 言語はとても助けになりえます Those of you who don't actually will be doing this very soon. Kotlinのコルーチンでは基本的に And the problem is, it's rather hard, actually, 非同期コードを書くのは to write sequential code. 同期コードを書くときと同じ Or it was hard before languages learned 同期コードでは何を使いますか? to support you in doing that, because a language can help you Loops if breaks そして continues there a lot. こういった物ですね So basically what we have with coroutines in Kotlin, 非同期コードで使うコルーチンも you're right asynchronous code the same way 同じもので 言語がすべてを監視しくれていて you write synchronous code. コード内で非同期計算を 複雑なコントロールフローで So what do you use in synchronous code? 表現する必要はありません Loops, ifs, breaks and continues, コールバックなし 複雑な機能ストラクチャーはなし things like that, right? ただのシーケンシャル風コードです And it's the same things you're using with coroutines クールですよね? for asynchronous code, so that the language keeps track ありがとう of everything and you don't have to express an intricate control コルーチンというアイディアは 基本的に flow for a synchronous computation in your code. 非同期と同期の同じ抽象化です No call backs, no fancy functional structures, これを理解するための 比喩としては it's just plain old sequential-looking code. スレッド無しとみなせます And isn't it cool? これが唯一のお見せするコード例です Thank you. 基本的に伝統的にスレッドでなされた 多くのことが So the idea with coroutines is that you basically コルーチンでできます have the same abstraction for asynchronous and synchronous. コルーチンはとても安価です And also, it's a nice metaphor to think of them スライドでは 100,000コルーチンを as almost free of threads. 作成するコードがあります Like here is the only code example I'm showing you. 考えてみてください Basically, very many things that are traditionally 100,000コルーチンが パラレルに存在し done with threads can be done with coroutines, 1 second待ち 1を返します but coroutines are extremely cheap. このプログラムは 1secondで完了します So here on the slide, I have a code that ほぼ1秒です コルーチンはもちろんすべて creates 100,000 coroutines. パラレルで待ちます Think about that. スレッドでやろうとしても 機能しません 100,000 coroutines existing in parallel, and each one of them 100,000スレッドは メモリにフィットしません waits for one second and returns one. 以上です So this program completes in, completes in one コルーチンで両得状況ですね second, almost one second, because all the coroutines wait 非常に効率的ですし in parallel, of course. コードはシンプルです But if you tried to do this with threads, it just doesn't work. コルーチンを試して見てください 100,000 threads don't fit into memory. 私たちの未来はおそらく That's it. 今よりも もっと非同期だと思うからです So with coroutines, it's a win-win situation. これで終わりです You get lots of performance, so it's very efficient, Kotlinについて知りたい方は ウェブサイトをチェックしてください and the code is simple. Androidのセクションがあります So take away here, check out coroutines, また このトークの後に 質疑応答セッションを行います because our future will likely to even more asynchronous Developer sandbox セクションCにお越しください than our present. 私とハディが質問にお答えします So I'm almost done, and if you want ご清聴いただき ありがとうございました to learn more about Kotlin, check out our website. We have a section for Android. And also, we'll have a question and answer session right after this talk, so come over to the Developer sandbox, section C. Myself and Hadi will be answering questions there. So thank you very much for your attention.
B1 中級 日本語 米 コード プロパティ 基本 拡張 タイプ プラットフォーム Kotlin入門(Google I/O '17 (Introduction to Kotlin (Google I/O '17)) 157 9 nctuharuka に公開 2021 年 01 月 14 日 シェア シェア 保存 報告 動画の中の単語