소스코드에 액세스하지 않고 함수를 기존 함수에 추가하는 것을 말한다. 코드로 보자.
class Square(val side: Double){
fun area(): Double{
return side * side;
}
}
// Extension function to calculate the perimeter of the square
fun Square.perimeter(): Double{
return 4 * side;
}
// Usage
fun main(args: Array<String>){
val square = Square(5.5);
val perimeterValue = square.perimeter()
println("Perimeter: $perimeterValue")
val areaValue = square.area()
println("Area: $areaValue")
}
다음은 단일 책임 원칙에 따라, 데이터의 형식을 지정하기 위해 클래스를 수정하는 대신 확장 함수를 사용한 예시다.
@Entity(tableName = "item")
data class Item(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "name")
val itemName: String,
@ColumnInfo(name = "price")
val itemPrice: Double,
@ColumnInfo(name = "quantity")
val quantityInStock: Int
)
fun Item.getFormattedPrice(): String =
NumberFormat.getCurrencyInstance().format(itemPrice)
@Entity(tableName = "messageList")
data class MessageList(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "reg_date")
val regDate: Long,
@ColumnInfo(name = "modify_date")
val modDate: Long,
val version: String,
@ColumnInfo(name = "message_list")
val messageList: List<Message>?
)
위와 같이 List 자료형을 쓰려고 했지만 room에서는 지원하지 않았다.
Cannot figure out how to save this field into database. You can consider adding a type converter for it. - messageList in hs.project.cof.data.db.MessageList
그래서 에러와 같이 type converter를 활용해 list를 써야했다. 다음 코드처럼 해보자.
data class와 같은 파일에 다음 컨버터 클래스를 만든다.
class MessageListConverters {
@TypeConverter
fun listToJson(value: List<Message>?) = Gson().toJson(value)
@TypeConverter
fun jsonToList(value: String) = Gson().fromJson(value, Array<Message>::class.java).toList()
}
database 추상 클래스에 @TypeConverters
주석을 단다.
@Database(entities = [MessageList::class], version = 1, exportSchema = false)
@TypeConverters(MessageListConverters::class)
abstract class MessageListDataBase : RoomDatabase() {
abstract fun MessageListDao(): MessageListDao
companion object {
@Volatile
private var INSTANCE: MessageListDataBase? = null
fun getDatabase(context: Context): MessageListDataBase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
MessageListDataBase::class.java,
"message_list_db"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
return instance
}
}
}
}