͓͢͠Δ͜ͱ w 8FCαʔόʔͬͯԿͯ͠Δͷʁ w 4DBMB
$MPKVSFʹ͍ͭͯ w 8FCαʔόʔΛ࡞Γͳ͕Βͭͷ+7.ݴޠΛֶ΅͏ w ͬ͘͟ΓΞʔΩςΫνϟ w ֤ݴޠͰ࣮ͯ͠ΈΔ w 4PDLFUͷѻ͍ w ਖ਼نදݱ w จࣈྻͷѻ͍ w Ϧιʔεͷཧ w ฒྻॲཧ w 8FCαʔόʔΛ࡞ͬͯɺԿΛಘͨʁ
4DBMB w +BWBͱͷ૬ޓӡ༻ੑ w γʔϜϨεͳݺͼग़͠ɺ+BWBඪ४ϥΠϒϥϦͷ࠶ར༻ w ؆ܿੑ w লུՄೳͳߏจɺܕਪɺڧྗͳඪ४ϥΠϒϥϦ w நͷߴ͍ίʔυɺ৽੍͍͠ޚߏจΛఆٛͰ͖Δදݱྗ w 8IBUͷڧௐɺ)PXͷӅณ w ੩తܕ͚ w ݕূՄೳੑɺϦϑΝΫλͷ͢͠͞ɺυΩϡϝϯτੑ
ࠓճ༻ҙ࣮ͨ͠ w ىಈ͠ɺMPDBMIPTUͷಛఆͷϙʔτͰ)551ϦΫΤετΛͪड͚Δ w ରԠ͢Δ)551ϦΫΤετϝιου(&5ͷΈ ͦΕҎ֎ͷϝιου(&5ͱΈͳ͢ w QVCMJDσΟϨΫτϦΑΓ্ͷ֊ͷϦΫΤετʹ 'PSCJEEFOΛฦ͢ w Ϧιʔεͷ.*.&֎෦ϑΝΠϧͰઃఆͰ͖Δ w ϦΫΤετΛϒϩοΫ͠ͳ͍ʢϚϧνεϨουʣ w ,FFQ"MJWF͠ͳ͍ɻίωΫγϣϯDMPTF͢Δ w )551$BDIF͠ͳ͍ɻฦ͞ͳ͍
4PDLFUͷѻ͍ // αʔόʔιέοτͷੜ val serverSocket = new ServerSocket(8080) while (true) { // ଓΛͪड͚Δɻଓ͞ΕΔ·ͰϒϩοΫ val socket = serverSocket.accept val in = s.getInputStream val out = s.getOutputStream ... } ιέοτͷੜͱଓͷͪड͚
4PDLFUͷѻ͍ʹֶ͍ͭͯΜͩ͜ͱ w 4FSWFS4PDLFUΦϒδΣΫτΛੜ͠ɺ ΫϥΠΞϯτ͔ΒͷଓΛBDDFQUͰͪड͚Δ w 4PDLFUΦϒδΣΫτʢΫϥΠΞϯτιέοτʣ͔Β *O0VUQVU4USFBN͕औಘͰ͖Δ w *OQVU4USFBN͔Β)551ϦΫΤετΛ3FBE͠ɺ 0VUQVU4USFBNʹ)551ϨεϙϯεΛ8SJUF͢Δ
ύλʔϯϚον w +BWBͷTXJUDIจʹࣅ͍ͯΔ͕ɺΑΓॊೈͰڧྗ w ʹҰக͢Δ͔͚ͩͰͳ͘ɺܕߏͰذͤ͞Δ͜ͱ͕Ͱ͖Δ 0 match { case 0 => "Zero" // "Zero" case _ => "Other" } List(1, 2, 3) match { case List(_, x, _) => x // 2 case _ => -1 } 1 match { x: Int => s"$xInt" // 1Int x: String => s"$xString" x => s"$x???" }
ύλʔϯϚον w ਖ਼نදݱΦϒδΣΫτʹରͯ͠Ϛονͤ͞Δ͜ͱ͕Ͱ͖Δ val Pattern = "(.+)/(.+)/(.+)".r //.rͰregexܕ “2021/05/20" match { case Pattern(y, m, d) => s"${y}${m}݄${d}" case _ => "???" }
0QUJPOܕ requestLine match { case pattern(method, path, version) => Some(Request(method, path, version)) case _ => None } w +BWBͰ͍͏0QUJPOBMʢΈ͍ͨͳͷʣ w )BTLFMMͰ͍͏.BZCF w 4PNFͱ/POF͔ΒͳΔܕʢతσʔλܕʣ w ͕͋Δ͔ͳ͍͔͔Βͳ͍ঢ়ଶΛද͢ w ͕ଘࡏ͢Δ͔ͷνΣοΫΛڧ੍Ͱ͖Δ
จࣈྻ݁߹ w ϨεϙϯεʢΦϒδΣΫτϚοϓʣ͔Β )551ϨεϙϯεϔομΛΈཱ͍ͯͨ public class Response { public final Status status; public final String contentType; public final int contentLength; public final byte[] body; }
w $MPKVSFͰจࣈྻͷ݁߹Ͱͳ͘TUS w ՄมҾɺ4ࣜͳΒͰ TUS (+ "hoge" "fuga") ClassCastException java.lang.String cannot be cast to java.lang.Number clojure.lang.Numbers.add (Numbers.java:128) (str "hoge" "fuga" "piyo") // => hogefugapiyo
5SZXJUI3FTPVSDFT try (InputStream in = new FileInputStream(file)) { // Կ͔ϦιʔεΛѻ͏ॲཧ } // try۟Λൈ͚ͨΒclose w USZ۟Λൈ͚ͨΒࣗಈͰDMPTF w ରKBWBJP$MPTFBCMF
KBWBMBOH"VUP$MPTFBCMFͷ࣮Ϋϥε
-PBO1BUUFSO w ʮआΓͨΒฦ͢ʯΛ࣮֬ʹߦ͏ͨΊͷΠσΟΦϜ w ͔͋ͨݴޠ੍͕࣋ͭޚߏͷΑ͏ͳϝιουΛɺ ϓϩάϥϚ͕؆୯ʹఆٛͰ͖Δͷ4DBMBͷΑ͍ͱ͜Ζ val reader = new BufferedReader(...) using(reader) { r => // readerΛͬͨԿ͔ͷॲཧ } // ϒϩοΫΛൈ͚ͨΒreaderclose͞Ε͍ͯΔ ˞4DBMB͔Βඪ४ϥΠϒϥϦʹˢͱ΄΅ಉͷTDBMBVUJM6TJOH͕Ճ͞Ε·͕ͨ͠ɺ ΠϝʔδΛ௫ΉͨΊʹࣗͰ࣮ͯ͠Έ·͢
-PBO1BUUFSO using(socket) { s => val in = s.getInputStream val out = s.getOutputStream val request = parser.fromInputStream(in) val response = request.map(handleRequest) response.foreach(_.writeTo(out)) } VTJOHϒϩοΫΛൈ͚ͨΒɺTPDLFUΛDMPTF͢Δ
8IBUͱ)PXͷ w ୈҰҾϒϩοΫlCPEZ5z w 8IBUʮԿΛ࣮ߦ͢Δ͔ʯ w ୈೋҾϒϩοΫlJNQMJDJUFYFDVUPS&YFDVUJPO$POUFYUz w )PXʮͲͷΑ͏ʹ࣮ߦ͢Δ͔ʯ w JNQMJDJUΩʔϫʔυ͕͍͍ͭͯΔͷͰɺ໌ࣔతʹҾͱͯ͢͠ඞཁͳ͠ w 'VUVSF EP4PNFUIJOH
JNQMJDJU8IBUͱ)PXͷ w )PX͕ڊେʹͳΔͱɺίʔυͷຊདྷͷҙਤ͕ຒΕͯ͠·͏ w JNQMJDJUͷେ͖ͳϞνϕʔγϣϯ)PXͷӅณ w 8IBUͱ)PXΛ͢Δ͜ͱͰɺతΛతʹࣔ͢͜ͱ͕Ͱ͖Δ val values: Seq[(String, Option[Int])] val sorted = sort(values)( tuple2Comparator( stringComparator, optionComparator(intComparator))) val sorted = sort(values) // implicit
*0όϯυ$16όϯυ ΞϓϦέʔγϣϯͷʮෛՙʯɺ *0όϯυͱ$16όϯυͷछྨʹେผ͞ΕΔ w *0όϯυ w *0͕ύϑΥʔϚϯεͷϘτϧωοΫ w $16ʮͪʯ͕ଟ͘ͳΔ w σΟεΫΞΫηεϦϞʔτ௨৴ͳͲ w$16όϯυ w $16͕ύϑΥʔϚϯεͷϘτϧωοΫ w $16ϑϧՔಇ w େنͳՊֶܭࢉͳͲ
ͦͷҰํͰ͜Μͳ͜ͱ w ؆୯ͦ͏ʹʮݟ͑ΔʯϑϧελοΫ8FCϑϨʔϜϫʔΫ w ͪΐͬͱ͍͜͜͠ͱΛΖ͏ͱ͢Δͱɺ্͙͢ख͍͔͘ͳ͘ͳΔ w ʮ)551ϨεϙϯεϔομΛݟΖʯ w ʮ$POUFOU5ZQF͕PDUFUTUSFBN͔ͩΒʜʯ w ʮNVMUJQBSUGPSNEBUB͕ʜʯ w ʮ+PJOͨͭ͠Γ͕αϒΫΤϦʹͳͬͯΔͷͰʁʯ w ʮ42-ͷ࣮ߦܭը͕ʜʯ
8FCϑϨʔϜϫʔΫͷʮநԽͷ࿙Εʯ w ϑϧελοΫͳ8FCϑϨʔϜϫʔΫ࿙Ε͕ݦஶ w ໘ͳ࡞ۀΛநԽ͠ɺ࡞ۀΛޮԽͯ͘͠ΕΔ w ͔͠͠໘ͳ෦ΛશʹӅณͯ͘͠ΕΔΘ͚Ͱͳ͍ w ͋͘·ͰʮޮԽʯͷͨΊͷநԽͰ͋Γɺ ʮԿ͕ى͖͍ͯΔ͔ʯΛҙࣝ͢Δඞཁ͕͋Δ w )551ɺ42-ɺ$16ɺϝϞϦɺ*0ɺωοτϫʔΫɺFUD
ಘͨͷͪΐͬͱਂ͘જΔ༐ؾ w ʮ࿙Εͷ͋ΔநԽʯͷͱͰɺղܾͷͨΊʹ ීஈ৮Δٕज़ͷԼͷϨΠϠʔʹજΔ͜ͱ͕ආ͚ΒΕͳ͍ ͔ͭɺ๛ͳใ͕͋ΔͱݶΒͳ͍ w 8FCαʔόʔΛ࡞Δ͜ͱͰɺ8FCϑϨʔϜϫʔΫ͕ͲΜͳࣄΛ ͍ͯ͠Δ͔ͳΜͱͳ͔͘ΔΑ͏ʹ w ӳޠͷҰ࣍ใʹͨΔ͕͍ͤͭͨ͘͜ͱͰɺ ະ༁ͷ৽͍ٕ͠ज़ͷυΩϡϝϯτͳͲԲͤͣಡΊΔΑ͏ʹ w ʮࣄͰ͍ͬͯΔϑϨʔϜϫʔΫϛυϧΣΞͷίʔυ ಡΜͰΈΑ͏ɻ͋ΘΑ͘ίϯτϦϏϡʔτͯ͠ΈΑ͏ʯͱ ͪΐͬͱਂ͘જͬͯΈΔ༐ؾˍڵຯΛ͖͔͚࣋ͭͬʹ