■ はじめに
https://dk521123.hatenablog.com/entry/2024/07/23/193246
で、sealed trait をやったが、 それを拡張するためのメソッドを追加したく、 イメージとしては、C#の拡張メソッドをScalaでやりたい。 Scala の implicit がやりたいことができそうなので、 メモしておく。
目次
【1】Implicit conversion 【2】implicit class 【3】import scala.language.implicitConversions 【4】サンプル 例1:Hello world 例2:Implicit parameter(文脈引き渡し) 例3:implicit class
【1】Implicit conversion
* 暗黙の型変換をユーザが定義できる機能 => 便利だが、使いすぎるとコードが追いづらくなる、、、 cf. implicit (インプリジット) = 暗黙の <-> explicit 明確な、明白な * 以下のサイトが分かりやすい
http://techtipshoge.blogspot.com/2019/06/scala-implicit.html
https://zenn.dev/at12/articles/7ac49ccbe4865b
https://scala-text.github.io/scala_text/implicit.html
【2】implicit class
* C#の拡張メソッドみたいに実装できる => 実装例は、「例3:implicit class」を参照
【C#】拡張メソッド
https://dk521123.hatenablog.com/entry/2011/02/22/224208
参考文献
https://blog.foresta.me/posts/scala-extension-method/
https://qiita.com/ka2kama/items/e696c0f0460cd5cefccb
https://zenn.dev/ababup1192/articles/29c7b3d4bf74bd
【3】import scala.language.implicitConversions
* implicit を使用した際の警告表示を抑制してくれる
https://docs.scala-lang.org/ja/tour/implicit-conversions.html
より抜粋 ~~~~~~~~ 暗黙の変換は見境なく使われると落とし穴になり得るため、 暗黙の変換の定義をコンパイルしている時にコンパイラは警告を出します。 警告をオフにするには、次のいずれかの措置を講じてください。 ・暗黙の変換定義のスコープにscala.language.implicitConversionsをインポートする。 ・コンパイラを-language:implicitConversionsをつけて起動する ・コンパイラにより変換が適用された時、警告は出ません。 ~~~~~~~~
【4】サンプル
例1:Hello world
object Main extends App { class Hello(val name: String) { def printHello(): Unit = { println(s"Hello, ${this.name}!!!") } } class World(val name: String) { def printWorld(): Unit = { println(s"World, ${this.name}...") } } // ★implicit で定義★ implicit def toWorld(hello: Hello): World = { new World(hello.name) } val hello = new Hello("Mike") hello.printHello // Hello, Mike!!! hello.printWorld // World, Mike... <= 勝手にtoWorldを呼び出してくれる }
例2:Implicit parameter(文脈引き渡し)
object Main extends App { def sayHi(greeting: String)(implicit name: String): Unit = { println(s"${greeting}, ${name}!!!") } // 暗黙のパラメータを事前に設定 implicit val name = "Mike" sayHi("Hello") // Hello, Mike!!! }
例3:implicit class
import ConfigType._ import scala.language.implicitConversions sealed trait ConfigType object ConfigType { final case class ConfigString(str: String) extends ConfigType final case class ConfigInt(int: Int) extends ConfigType final case class ConfigBoolean(bool: Boolean) extends ConfigType final case class ConfigStrings(list: List[String]) extends ConfigType def toConfigType[T](value: T): ConfigType = { value match { case intValue: Int => ConfigInt(intValue) case boolValue: Boolean => ConfigBoolean(boolValue) case stringValue: String => ConfigString(stringValue) case listValues: List[String] => ConfigStrings(listValues) case _ => throw new IllegalArgumentException("No supported") } } // ★implicit classを使う★ implicit class ConfigTypeEx(val self: ConfigType) { // ★C#の拡張メソッドっぽく呼び出せる final def toPrintStr: String = { self match { case intValue: ConfigInt => s"Int - ${intValue.int}" case boolValue: ConfigBoolean => s"Boolean - ${boolValue.bool}" case stringValue: ConfigString => s"String - ${stringValue.str}" case listValues: ConfigStrings => s"List - ${listValues.list.mkString(",")}" case _ => "No supported" } } } } object Hello { def main(args: Array[String]): Unit = { val mapper: Map[String, ConfigType] = Map( "key1" -> toConfigType("Hello"), "key2" -> toConfigType(2), "key3" -> toConfigType(true), "key4" -> toConfigType(List("value4_1", "value4_2", "value4_3")) ) mapper.foreach { case (key: String, value: ConfigType) => // ★value.toPrintStrを注目★ println(s"${key} - ${value.toPrintStr}}") } } }
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ コレクションで使えるメソッド ~
https://dk521123.hatenablog.com/entry/2023/09/07/223422
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 基本編 / 繰り返し ~
https://dk521123.hatenablog.com/entry/2023/01/24/000000
Scala ~ 基本編 / トレイト ~
https://dk521123.hatenablog.com/entry/2023/09/10/204016
Scala ~ 基本編 / パターンマッチング ~
https://dk521123.hatenablog.com/entry/2023/06/06/233614
Scala ~ Enum ~
https://dk521123.hatenablog.com/entry/2023/01/05/000000
Scala ~ asInstanceOf / isInstanceOf ~
https://dk521123.hatenablog.com/entry/2024/07/26/225713
【C#】拡張メソッド
https://dk521123.hatenablog.com/entry/2011/02/22/224208