Kotlin 泛型案例详解
泛型是Kotlin中强大的类型安全工具,允许编写可重用的代码而不牺牲类型安全。下面通过多个实际案例来详细讲解。
1. 基础泛型概念
1.1 基本泛型类
// 泛型类
class Box<T>(private var content: T) {
fun getContent(): T = content
fun setContent(newContent: T) {
content = newContent
}
fun isEmpty(): Boolean = content == null
override fun toString(): String = "Box(content=$content)"
}
// 使用
val intBox = Box(42) // 类型推断为 Box<Int>
val stringBox = Box("Hello") // Box<String>
println(intBox.getContent()) // 42
println(stringBox.getContent()) // Hello
// 编译时类型安全
// stringBox.setContent(42) // 编译错误:类型不匹配
1.2 多类型参数
// 多个泛型参数
class Pair<K, V>(val key: K, val value: V) {
fun swap(): Pair<V, K> = Pair(value, key)
override fun toString(): String = "($key -> $value)"
}
// 使用
val pair1 = Pair("name", "Alice")
val pair2 = Pair(1, "One")
val swapped = pair1.swap() // Pair("Alice", "name")
println(pair1) // (name -> Alice)
println(pair2) // (1 -> One)
println(swapped) // (Alice -> name)
2. 泛型函数
2.1 泛型扩展函数
// 泛型扩展函数
fun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {
val result = mutableListOf<T>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}
// 使用
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = numbers.customFilter { it % 2 == 0 }
println(evenNumbers) // [2, 4, 6]
val names = listOf("Alice", "Bob", "Charlie", "David")
val longNames = names.customFilter { it.length > 4 }
println(longNames) // [Alice, Charlie]
2.2 泛型工具函数
// 泛型工具函数示例
fun <T : Comparable<T>> findMax(items: List<T>): T? {
if (items.isEmpty()) return null
var max = items[0]
for (item in items) {
if (item > max) {
max = item
}
}
return max
}
fun <T> List<T>.shuffle(): List<T> {
val result = this.toMutableList()
for (i in result.indices) {
val randomIndex = (0 until result.size).random()
val temp = result[i]
result[i] = result[randomIndex]
result[randomIndex] = temp
}
return result
}
// 使用
val numbers = listOf(5, 2, 8, 1, 9, 3)
println("Max: ${findMax(numbers)}") // Max: 9
val words = listOf("apple", "zebra", "banana", "cat")
println("Max word: ${findMax(words)}") // Max word: zebra
println("Shuffled: ${numbers.shuffle()}")
3. 泛型约束
3.1 类型上界约束
// 上界约束:T 必须是 Number 或其子类
class NumberContainer<T : Number>(private val value: T) {
fun doubleValue(): Double = value.toDouble() * 2
fun <U : Number> add(other: NumberContainer<U>): Double {
return this.value.toDouble() + other.value.toDouble()
}
}
// 多重约束
interface Readable {
fun read(): String
}
interface Writable {
fun write(content: String)
}
class Document<T>(private var content: T) where T : Readable, T : Writable {
fun process() {
println("Reading: ${content.read()}")
content.write("Modified content")
println("After writing: ${content.read()}")
}
}
class SmartDocument : Readable, Writable {
private var text = "Initial content"
override fun read(): String = text
override fun write(content: String) {
text = content
}
}
// 使用
val intContainer = NumberContainer(10)
val doubleContainer = NumberContainer(3.14)
println(intContainer.doubleValue()) // 20.0
println(doubleContainer.doubleValue()) // 6.28
println(intContainer.add(doubleContainer)) // 13.14
val doc = Document(SmartDocument())
doc.process()
3.2 非空约束
// 确保泛型参数非空
class NonNullContainer<T : Any>(private var item: T) {
fun get(): T = item
fun update(newItem: T) {
item = newItem
}
// 使用 reified 类型参数
inline fun <reified R> castIfPossible(): R? {
return if (item is R) item as R else null
}
}
// 使用
val container = NonNullContainer("Hello")
// val nullableContainer = NonNullContainer(null) // 编译错误:类型不匹配
val castedInt: Int? = container.castIfPossible()
val castedString: String? = container.castIfPossible()
println(castedInt) // null
println(castedString) // Hello
4. 型变(Variance)
4.1 协变(out)
// 协变示例:生产者,只读
interface Producer<out T> {
fun produce(): T
// fun consume(item: T) // 错误:协变类型不能作为参数
}
class StringProducer : Producer<String> {
override fun produce(): String = "String from producer"
}
class IntProducer : Producer<Int> {
override fun produce(): Int = 42
}
// 使用协变
fun printProducerOutput(producer: Producer<Any>) {
println(producer.produce())
}
// 使用
val stringProducer: Producer<String> = StringProducer()
val intProducer: Producer<Int> = IntProducer()
// 协变允许将 Producer<String> 赋值给 Producer<Any>
printProducerOutput(stringProducer) // String from producer
printProducerOutput(intProducer) // 42
// 协变集合示例
fun copyFromTo(from: List<out Number>, to: MutableList<Number>) {
for (item in from) {
to.add(item)
}
}
val intList = listOf(1, 2, 3)
val numberList = mutableListOf<Number>()
copyFromTo(intList, numberList)
println(numberList) // [1, 2, 3]
4.2 逆变(in)
// 逆变示例:消费者,只写
interface Consumer<in T> {
fun consume(item: T)
// fun produce(): T // 错误:逆变类型不能作为返回值
}
class AnyConsumer : Consumer<Any> {
override fun consume(item: Any) {
println("Consuming: $item (${item::class.simpleName})")
}
}
class StringConsumer : Consumer<String> {
override fun consume(item: String) {
println("Consuming string: $item")
}
}
// 使用逆变
fun processString(consumer: Consumer<String>) {
consumer.consume("Hello")
}
// 使用
val anyConsumer: Consumer<Any> = AnyConsumer()
val stringConsumer: Consumer<String> = StringConsumer()
// 逆变允许将 Consumer<Any> 赋值给 Consumer<String>
processString(anyConsumer) // Consuming: Hello (String)
processString(stringConsumer) // Consuming string: Hello
// 逆变比较器示例
fun sortStrings(strings: MutableList<String>, comparator: Comparator<in String>) {
strings.sortWith(comparator)
}
val anyComparator = Comparator<Any> { a, b ->
a.toString().compareTo(b.toString())
}
val strings = mutableListOf("banana", "apple", "cherry")
sortStrings(strings, anyComparator)
println(strings) // [apple, banana, cherry]
4.3 不变(invariant)
// 不变示例:既是生产者又是消费者
class Container<T>(private var item: T) {
fun getItem(): T = item
fun setItem(newItem: T) {
item = newItem
}
}
// 使用
val stringContainer: Container<String> = Container("Initial")
stringContainer.setItem("Updated")
println(stringContainer.getItem()) // Updated
// 以下代码会导致编译错误
// val anyContainer: Container<Any> = stringContainer // 错误:类型不匹配
// anyContainer.setItem(42) // 如果可以,这将破坏类型安全
5. 星投影(Star Projection)
// 星投影示例
class Storage<out T : Any>(private val items: List<T>) {
fun getFirst(): T? = items.firstOrNull()
fun getAll(): List<T> = items
// 使用星投影作为参数
fun compareFirst(other: Storage<*>): Boolean {
return this.getFirst() == other.getFirst()
}
}
// 使用星投影
fun printStorageInfo(storage: Storage<*>) {
println("First item: ${storage.getFirst()}")
println("All items: ${storage.getAll()}")
}
// 使用
val intStorage = Storage(listOf(1, 2, 3))
val stringStorage = Storage(listOf("A", "B", "C"))
printStorageInfo(intStorage)
printStorageInfo(stringStorage)
println("First items equal? ${intStorage.compareFirst(stringStorage)}")
6. reified 类型参数
// reified 类型参数(只能用于 inline 函数)
inline fun <reified T> List<*>.filterByType(): List<T> {
return this.filter { it is T }.map { it as T }
}
inline fun <reified T> createInstance(vararg args: Any): T? {
return try {
val constructor = T::class.java.constructors.find {
it.parameterCount == args.size
}
constructor?.newInstance(*args) as? T
} catch (e: Exception) {
null
}
}
// 使用
val mixedList = listOf(1, "Hello", 2, "World", 3.14, 4)
val strings: List<String> = mixedList.filterByType()
val ints: List<Int> = mixedList.filterByType()
val doubles: List<Double> = mixedList.filterByType()
println("Strings: $strings") // [Hello, World]
println("Ints: $ints") // [1, 2, 4]
println("Doubles: $doubles") // [3.14]
// 创建实例
data class Person(val name: String, val age: Int)
val person: Person? = createInstance("Alice", 30)
println(person) // Person(name=Alice, age=30)
7. 泛型在实际项目中的应用
7.1 数据访问层泛型
// 泛型 Repository 模式
interface Repository<T, ID> {
fun findById(id: ID): T?
fun findAll(): List<T>
fun save(entity: T): T
fun deleteById(id: ID): Boolean
fun count(): Long
}
abstract class GenericRepository<T, ID> : Repository<T, ID> {
protected val storage = mutableMapOf<ID, T>()
override fun findById(id: ID): T? = storage[id]
override fun findAll(): List<T> = storage.values.toList()
override fun save(entity: T): T {
val id = extractId(entity)
storage[id] = entity
return entity
}
override fun deleteById(id: ID): Boolean = storage.remove(id) != null
override fun count(): Long = storage.size.toLong()
protected abstract fun extractId(entity: T): ID
}
// 具体实现
data class User(val id: Long, val name: String, val email: String)
data class Product(val id: String, val name: String, val price: Double)
class UserRepository : GenericRepository<User, Long>() {
override fun extractId(entity: User): Long = entity.id
fun findByEmail(email: String): User? {
return storage.values.find { it.email == email }
}
}
class ProductRepository : GenericRepository<Product, String>() {
override fun extractId(entity: Product): String = entity.id
fun findExpensiveProducts(threshold: Double): List<Product> {
return storage.values.filter { it.price > threshold }
}
}
// 使用
val userRepo = UserRepository()
userRepo.save(User(1, "Alice", "alice@email.com"))
userRepo.save(User(2, "Bob", "bob@email.com"))
println(userRepo.findAll())
println(userRepo.findByEmail("bob@email.com"))
val productRepo = ProductRepository()
productRepo.save(Product("P1", "Laptop", 999.99))
productRepo.save(Product("P2", "Mouse", 29.99))
println(productRepo.findExpensiveProducts(100.0))
7.2 泛型事件系统
// 泛型事件系统
interface Event
data class UserCreatedEvent(val userId: String, val userName: String) : Event
data class OrderPlacedEvent(val orderId: String, val amount: Double) : Event
data class PaymentProcessedEvent(val paymentId: String, val success: Boolean) : Event
// 泛型事件处理器
interface EventHandler<in T : Event> {
fun handle(event: T)
}
// 具体处理器
class UserCreatedHandler : EventHandler<UserCreatedEvent> {
override fun handle(event: UserCreatedEvent) {
println("User created: ${event.userName} (ID: ${event.userId})")
// 发送欢迎邮件、创建用户目录等
}
}
class OrderPlacedHandler : EventHandler<OrderPlacedEvent> {
override fun handle(event: OrderPlacedEvent) {
println("Order placed: ${event.orderId} for \$${event.amount}")
// 更新库存、通知发货部门等
}
}
// 事件总线
class EventBus {
private val handlers = mutableMapOf<Class<*>, MutableList<EventHandler<*>>>()
fun <T : Event> registerHandler(eventClass: Class<T>, handler: EventHandler<T>) {
handlers.getOrPut(eventClass) { mutableListOf() }.add(handler)
}
fun <T : Event> publish(event: T) {
val eventClass = event::class.java
handlers[eventClass]?.forEach { handler ->
@Suppress("UNCHECKED_CAST")
(handler as EventHandler<T>).handle(event)
}
}
inline fun <reified T : Event> register(noinline handler: (T) -> Unit) {
registerHandler(T::class.java, object : EventHandler<T> {
override fun handle(event: T) = handler(event)
})
}
}
// 使用
val eventBus = EventBus()
// 注册处理器
eventBus.registerHandler(UserCreatedEvent::class.java, UserCreatedHandler())
eventBus.registerHandler(OrderPlacedEvent::class.java, OrderPlacedHandler())
// 使用 reified 注册 Lambda 处理器
eventBus.register<PaymentProcessedEvent> { event ->
println("Payment processed: ${event.paymentId}, success: ${event.success}")
}
// 发布事件
eventBus.publish(UserCreatedEvent("U123", "Alice"))
eventBus.publish(OrderPlacedEvent("O456", 99.99))
eventBus.publish(PaymentProcessedEvent("P789", true))
7.3 泛型缓存系统
// 泛型缓存接口
interface Cache<K, V> {
fun put(key: K, value: V)
fun get(key: K): V?
fun remove(key: K)
fun clear()
fun size(): Int
fun getAll(): Map<K, V>
}
// 基于时间的缓存实现
class TimedCache<K, V>(
private val defaultTtl: Long = 60000, // 默认60秒
private val maxSize: Int = 1000
) : Cache<K, V> {
private data class CacheEntry<V>(
val value: V,
val timestamp: Long = System.currentTimeMillis()
)
private val storage = linkedMapOf<K, CacheEntry<V>>()
override fun put(key: K, value: V) {
cleanup()
if (storage.size >= maxSize) {
storage.remove(storage.keys.first())
}
storage[key] = CacheEntry(value)
}
override fun get(key: K): V? {
cleanup()
val entry = storage[key] ?: return null
return entry.value
}
override fun remove(key: K) {
storage.remove(key)
}
override fun clear() {
storage.clear()
}
override fun size(): Int {
cleanup()
return storage.size
}
override fun getAll(): Map<K, V> {
cleanup()
return storage.mapValues { it.value.value }
}
// 清理过期条目
private fun cleanup() {
val now = System.currentTimeMillis()
val expiredKeys = storage.filter {
now - it.value.timestamp > defaultTtl
}.keys
expiredKeys.forEach { storage.remove(it) }
}
// 带TTL的put
fun put(key: K, value: V, ttl: Long) {
val entry = CacheEntry(value, System.currentTimeMillis())
storage[key] = entry
}
}
// 使用缓存
fun main() {
val userCache = TimedCache<String, User>(ttl = 30000) // 30秒TTL
// 模拟获取用户(从缓存或数据库)
fun getUser(userId: String): User? {
return userCache.get(userId) ?: run {
// 从数据库获取
val user = fetchUserFromDatabase(userId)
user?.let { userCache.put(userId, it) }
user
}
}
fun fetchUserFromDatabase(userId: String): User? {
println("Fetching user $userId from database...")
// 模拟数据库延迟
Thread.sleep(100)
return when (userId) {
"U1" -> User("U1", "Alice", "alice@email.com")
"U2" -> User("U2", "Bob", "bob@email.com")
else -> null
}
}
// 测试
println("First call (from DB):")
println(getUser("U1"))
println("\nSecond call (from cache):")
println(getUser("U1"))
println("\nCache size: ${userCache.size()}")
println("All cached users: ${userCache.getAll()}")
}
7.4 泛型验证框架
// 泛型验证器
interface Validator<T> {
fun validate(value: T): ValidationResult
}
data class ValidationResult(
val isValid: Boolean,
val errors: List<String> = emptyList()
) {
companion object {
val valid = ValidationResult(true)
fun invalid(vararg errors: String) =
ValidationResult(false, errors.toList())
}
}
// 组合验证器
class CompositeValidator<T>(
private vararg val validators: Validator<T>
) : Validator<T> {
override fun validate(value: T): ValidationResult {
val errors = mutableListOf<String>()
for (validator in validators) {
val result = validator.validate(value)
if (!result.isValid) {
errors.addAll(result.errors)
}
}
return if (errors.isEmpty()) {
ValidationResult.valid
} else {
ValidationResult.invalid(*errors.toTypedArray())
}
}
}
// 具体验证器实现
class NotEmptyValidator : Validator<String> {
override fun validate(value: String): ValidationResult {
return if (value.isNotBlank()) {
ValidationResult.valid
} else {
ValidationResult.invalid("Value cannot be empty")
}
}
}
class MinLengthValidator(private val minLength: Int) : Validator<String> {
override fun validate(value: String): ValidationResult {
return if (value.length >= minLength) {
ValidationResult.valid
} else {
ValidationResult.invalid("Value must be at least $minLength characters")
}
}
}
class MaxLengthValidator(private val maxLength: Int) : Validator<String> {
override fun validate(value: String): ValidationResult {
return if (value.length <= maxLength) {
ValidationResult.valid
} else {
ValidationResult.invalid("Value must be at most $maxLength characters")
}
}
}
class EmailValidator : Validator<String> {
private val emailRegex = Regex("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\$")
override fun validate(value: String): ValidationResult {
return if (emailRegex.matches(value)) {
ValidationResult.valid
} else {
ValidationResult.invalid("Invalid email format")
}
}
}
class RangeValidator<T : Comparable<T>>(
private val min: T,
private val max: T
) : Validator<T> {
override fun validate(value: T): ValidationResult {
return if (value in min..max) {
ValidationResult.valid
} else {
ValidationResult.invalid("Value must be between $min and $max")
}
}
}
// 验证器构建器(DSL风格)
class ValidatorBuilder<T> {
private val validators = mutableListOf<Validator<T>>()
fun add(validator: Validator<T>) {
validators.add(validator)
}
fun build(): Validator<T> {
return CompositeValidator(*validators.toTypedArray())
}
// DSL方法
fun validate(block: (T) -> ValidationResult) {
add(object : Validator<T> {
override fun validate(value: T): ValidationResult = block(value)
})
}
}
// 使用
fun main() {
// 创建用户验证器
val userEmailValidator = CompositeValidator(
NotEmptyValidator(),
EmailValidator(),
MaxLengthValidator(100)
)
val userPasswordValidator = CompositeValidator(
NotEmptyValidator(),
MinLengthValidator(8),
MaxLengthValidator(50)
)
val ageValidator = RangeValidator(0, 150)
// 测试验证器
println("Email validation:")
println(userEmailValidator.validate("test@example.com")) // valid
println(userEmailValidator.validate("invalid-email")) // invalid
println(userEmailValidator.validate("")) // invalid
println("\nPassword validation:")
println(userPasswordValidator.validate("12345678")) // valid
println(userPasswordValidator.validate("123")) // invalid
println("\nAge validation:")
println(ageValidator.validate(25)) // valid
println(ageValidator.validate(200)) // invalid
// 使用构建器创建复杂验证器
val userValidatorBuilder = ValidatorBuilder<String>().apply {
add(NotEmptyValidator())
add(MinLengthValidator(3))
add(MaxLengthValidator(20))
validate { value ->
if (value.all { it.isLetterOrDigit() }) {
ValidationResult.valid
} else {
ValidationResult.invalid("Username must contain only letters and digits")
}
}
}
val usernameValidator = userValidatorBuilder.build()
println("\nUsername validation:")
println(usernameValidator.validate("Alice123")) // valid
println(usernameValidator.validate("Al")) // invalid (too short)
println(usernameValidator.validate("Alice@123")) // invalid (contains @)
}
7.5 泛型API响应包装器
// 泛型API响应模型
sealed class ApiResponse<out T> {
data class Success<out T>(val data: T, val code: Int = 200) : ApiResponse<T>()
data class Error(val message: String, val code: Int, val exception: Throwable? = null) : ApiResponse<Nothing>()
data class Loading(val progress: Float? = null) : ApiResponse<Nothing>()
inline fun <R> map(transform: (T) -> R): ApiResponse<R> {
return when (this) {
is Success -> Success(transform(data), code)
is Error -> this
is Loading -> this
}
}
inline fun onSuccess(action: (T) -> Unit): ApiResponse<T> {
if (this is Success) action(data)
return this
}
inline fun onError(action: (String, Int) -> Unit): ApiResponse<T> {
if (this is Error) action(message, code)
return this
}
inline fun onLoading(action: (Float?) -> Unit): ApiResponse<T> {
if (this is Loading) action(progress)
return this
}
}
// 模拟API调用
suspend fun <T> simulateApiCall(
data: T? = null,
delayMillis: Long = 1000,
shouldFail: Boolean = false
): ApiResponse<T> {
// 模拟加载
kotlinx.coroutines.delay(500)
return if (shouldFail) {
ApiResponse.Error("API call failed", 500, RuntimeException("Simulated error"))
} else {
if (data == null) {
ApiResponse.Error("No data available", 404)
} else {
ApiResponse.Success(data, 200)
}
}
}
// 使用
suspend fun main() {
// 模拟用户API调用
val userResponse: ApiResponse<User> = simulateApiCall(
data = User("U1", "Alice", "alice@email.com"),
delayMillis = 1000,
shouldFail = false
)
// 处理响应
userResponse
.onLoading { progress ->
println("Loading user... ${progress?.let { "${(it * 100).toInt()}%" } ?: ""}")
}
.onSuccess { user ->
println("User loaded: ${user.name}")
}
.onError { message, code ->
println("Error loading user ($code): $message")
}
// 使用map转换数据
val userNamesResponse = userResponse.map { it.name }
when (userNamesResponse) {
is ApiResponse.Success -> println("Username: ${userNamesResponse.data}")
is ApiResponse.Error -> println("Error: ${userNamesResponse.message}")
is ApiResponse.Loading -> println("Loading...")
}
// 处理产品列表
val products = listOf(
Product("P1", "Laptop", 999.99),
Product("P2", "Mouse", 29.99),
Product("P3", "Keyboard", 79.99)
)
val productsResponse: ApiResponse<List<Product>> = simulateApiCall(products)
val expensiveProducts = productsResponse
.map { productList ->
productList.filter { it.price > 100.0 }
}
.onSuccess { expensive ->
println("Expensive products: ${expensive.joinToString { it.name }}")
}
}
8. 高级泛型技巧
8.1 泛型委托属性
// 泛型委托属性
class ObservableProperty<T>(
initialValue: T,
private val onChange: (oldValue: T, newValue: T) -> Unit
) {
private var value = initialValue
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): T = value
operator fun setValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>, newValue: T) {
val oldValue = value
value = newValue
onChange(oldValue, newValue)
}
}
// 使用委托属性
class UserProfile {
var name: String by ObservableProperty("") { old, new ->
println("Name changed from '$old' to '$new'")
}
var age: Int by ObservableProperty(0) { old, new ->
println("Age changed from $old to $new")
}
var email: String by ObservableProperty("") { old, new ->
if (new.isNotEmpty() && !new.contains("@")) {
println("Warning: Invalid email format")
}
}
}
// 测试
fun main() {
val profile = UserProfile()
profile.name = "Alice"
profile.age = 30
profile.email = "alice@example.com"
profile.email = "invalid-email" // 会显示警告
println("\nFinal values:")
println("Name: ${profile.name}")
println("Age: ${profile.age}")
println("Email: ${profile.email}")
}
8.2 泛型类型别名
// 泛型类型别名
typealias StringMap<V> = Map<String, V>
typealias Callback<T> = (T) -> Unit
typealias Predicate<T> = (T) -> Boolean
typealias Factory<T> = () -> T
typealias Processor<in I, out O> = (I) -> O
// 使用类型别名
class EventProcessor {
private val handlers = mutableMapOf<String, Callback<Any>>()
fun <T> registerEvent(eventName: String, handler: Callback<T>) {
@Suppress("UNCHECKED_CAST")
handlers[eventName] = handler as Callback<Any>
}
fun <T> triggerEvent(eventName: String, data: T) {
handlers[eventName]?.invoke(data)
}
}
// 函数式组合
fun <T> Predicate<T>.and(other: Predicate<T>): Predicate<T> = { this(it) && other(it) }
fun <T> Predicate<T>.or(other: Predicate<T>): Predicate<T> = { this(it) || other(it) }
fun <T> Predicate<T>.not(): Predicate<T> = { !this(it) }
// 使用
fun main() {
val isEven: Predicate<Int> = { it % 2 == 0 }
val isPositive: Predicate<Int> = { it > 0 }
val isEvenAndPositive: Predicate<Int> = isEven.and(isPositive)
val isEvenOrPositive: Predicate<Int> = isEven.or(isPositive)
val isOdd: Predicate<Int> = isEven.not()
println("Is 4 even and positive? ${isEvenAndPositive(4)}") // true
println("Is -2 even and positive? ${isEvenAndPositive(-2)}") // false
println("Is -2 even or positive? ${isEvenOrPositive(-2)}") // true
println("Is 3 odd? ${isOdd(3)}") // true
}
9. 泛型的最佳实践
- 类型安全优先:充分利用编译时类型检查
- 适当的约束:使用泛型约束限制类型参数的范围
- 避免过度泛化:不是所有代码都需要泛型
- 使用型变:正确使用
in和out提高API灵活性 - 文档化:为复杂的泛型API提供清晰的文档
- 测试:编写针对泛型边界情况的测试
总结
Kotlin泛型提供了强大的类型安全抽象能力。通过合理使用泛型类、泛型函数、型变、reified类型参数等特性,可以创建出灵活、可重用且类型安全的代码。实际项目中,泛型在Repository模式、缓存系统、验证框架、API响应处理等方面都有广泛应用。