値の代入方法の違い
まず、StringとCharでは変数に値を代入する方法が微妙に異なります。具体的には、Stringは "
(ダブルクォート)で囲い、Charは '
(シングルクォート)で囲みます。
StringとCharを区別しないプログラミング言語では、"
(ダブルクォート)でも '
(シングルクォート)でもどちらで囲んでも良い(違いが生じない)場合もありますが、Kotlinでは意図せず囲む記号を間違えてしまったらエラーの原因になり得るので注意が必要です。
val str = "Hello, World!" // String
val charA = 'A' // Char
val name = 'Tom' // It causes an error!
ちなみに、単一の文字を文字列(String)として定義することは可能であり、逆のパターン(複数の文字列をCharとして定義する)と違ってエラーにはなりません。ただ、当然ですがデータ型を明確に定義する場合においてはエラーとなります。
val oneStr = "A" // OK (Type: String)
val charValue: Char = "B" // NG
『複数の文字をString型として定義したつもりがChar型になっていた』ということは基本的にあり得ません(エラーになるため)が、『単一の文字をChar型として定義したつもりがString型になってしまっていた』…ということはあり得るので、気をつけましょう。
両者はどう違う?
String型もChar型も『文字』を扱うデータ型であることは共通していますが、Stringは文字の集合(文字列)を扱うためのものであるのに対し、Charは単一の文字を扱うためのものです。
そのためStringクラスのプロパティやメソッドは、複数の文字から得られる情報や、複数の文字を操作するようなものが用意されています。
代表的なものでいえば、文字列の文字数を得るための length
プロパティや、文字列を任意の数で分解して List
を得る chunked()
などがあります。
val kotlin = "Kotlin"
println(kotlin.length) // 6
println(kotlin.chunked(2)) // [Ko, tl, in]
これらのプロパティ・メソッドは、当然のことながらCharクラスには存在しません。一方、Charクラスには単一の文字から得られる情報を取得するためのプロパティやメソッドが用意されています。
具体的には、その文字のカテゴリ情報を取得する category
や、その文字がアルファベットや平仮名ではなく数字かどうかを判定する isDigit()
などがあります。
val charA = 'A'
val char1 = '1'
println(charA.category) // UPPERCASE_LETTER
println(char1.isDigit()) // true
このように使用できるプロパティ・メソッドが異なるので、必要に応じてString型とChar型を使い分けることが重要となります。基本的には、単一の文字しか扱わない場合においてはStringである必要はなく、Charとして定義・管理した方が適切であると言えます。
ちなみに uppercase()
など、String型・Char型に共通する(同じ名称の)メソッドもあります。uppercase()
メソッドは文字(列)を大文字にするためのもので、基本的な使い方や使用目的も共通しています。
val kotlin = "Kotlin"
val charValue = 'a'
println(kotlin.uppercase()) // KOTLIN
println(charValue.uppercase()) // A
なので、『StringとCharでは、使用できる全てのプロパティ・メソッドの名称や効果が異なる』というふうに拡大解釈してしまわないように注意が必要です。
Charの具体的な利用シーン
『Stringの具体的な利用シーンが想像できない』というケースはまずないかと思いますが、『Charっていつ使うの?』と疑問に思う人はいるかもしれません。
ということで、最後にCharの具体的な利用シーンを確認しておきたいと思います。
たとえばユーザーをいくつかのグループに分けるため、アルファベット(A~Z)を用いて管理するケースを考えてみましょう。このとき、アルファベットを文字列(String)として管理することもできますが、一文字しか使わないのであれば、次のようにCharで定義することができます。
data class User (
val id: Int,
val group: Char,
val name: String
)
val userA = User(
id = 1,
group = 'A',
name = "Tom"
)
val userB = User(
id = 2,
group = 'B',
name = "Marie"
)
このように group
を Char
、name
を String
として定義することで両者の違いがより明確になり、管理しやすくなるというメリットが生じます。データ型をチェックするだけで、値が group
なのか name
なのかを判別できますからね。
ここで紹介した例はほんの一例であり、この他にもChar型を活用できるケースは色々あります。何らかの変数を宣言する際、値が単一の文字であるならば、『この場面ではChar型をうまく活用できないかな?』と考えてみると良いかもしれません。