我正在尝试在实践中使用 Kotlin 中的新sealedSubclasses
功能。我需要处理来自密封类的一些子类的实例,但是我以前不知道哪个子类是,所以正常的过程是尝试所有子类。
假设有20个或更多子类。
下面,我对其进行了很多简化以使其易于遵循。我只使用了2个具有标量内部类型的子类。在现实世界中可能是复杂的对象类型。
sealed class Person {
abstract var name:String
// ...
}
data class Doctor(
var license: String = "",
// ....
override var name:String = ""
) : Person()
// ....
data class Fireman (
var medals: Int=0,
// ....
override var name:String = ""
) : Person()
现在我需要克隆该结构:首先尝试:
var p:Person = Doctor("123","Louis")
var q:Person
// ...
Person.copy // it is forbidden
所以我需要做
var p:Person = Doctor("123","Louis")
var q:Person
when (p) {
is Doctor -> q = p.copy()
// ...
is Fireman -> q = p.copy()
}
请注意,这是错误的代码,因为总是添加新的子类,因此必须在克隆过程中手动添加,重复子块。
所以我尝试使用sealedSubclasses
,但是为了模拟前面的代码,我没有将子类与类型连接起来
for(令牌中的子类:: class.sealedSubclasses){ 如果(ele :: class.simpleName as String == metadata.qualifiedName){ // ?????? } }
我该怎么办?
答案 0 :(得分:1)
解决问题的一种方法是创建自己的抽象sealed class Person {
abstract val name: String
}
data class Doctor(
override val name: String,
val license: String,
val extraProperty: Any
) : Person()
data class Fireman(
override var name: String,
val medals: Int
) : Person()
val p: Person = Doctor("123", "Louis", "extra")
var q: Person = when (p) {
is Doctor -> p.copy(name = "New name", license = "Other license", extraProperty = "extra2")
is Fireman -> p.copy(name = "New Name", medals = 15)
// And so on...
}
方法的实现:
@IBAction func searchButtonTapped(_ sender: Any) {
if searchBar.isHidden == true {
searchBar.isHidden = false
self.navigationItem.titleView = self.searchBar
searchActive = true
} else if searchBar.isHidden == false {
searchBar.isHidden = true
searchActive = false
let label = UILabel()
label.text = "My Title"
label.textColor = .red
self.navigationItem.titleView = label
}
}
此帖子https://stackoverflow.com/a/47624138/3542143中有人遇到了与您类似的问题
答案 1 :(得分:1)
如果愿意,您可以可以通过反思来实现,但是我认为test_list= [['Alabama', {'Baldwin County': 182265}],
['Alabama', {'Barbour County': 27457}],
['Arkansas', {'Newton County': 8330}],
['Arkansas', {'Perry County': 10445}],
['Arkansas', {'Phillips County': 21757}],
['California', {'Madera County': 150865}],
['California', {'Marin County': 252409}],
['Colorado', {'Adams County': 441603}],
['Colorado', {'Alamosa County': 15445}],
['Colorado', {'Arapahoe County': 572003}]
]
不会有用。大约(未试用):
test_list1= [['Alabama', {'Baldwin County': 182265, 'Barbour County': 27457}],
['Arkansas', {'Newton County': 8330, 'Perry County': 10445, 'Phillips County': 21757}],
['California', {'Madera County': 150865, 'Marin County': 252409}],
['Colorado', {'Adams County': 441603, 'Alamosa County': 15445, 'Arapahoe County': 572003}]
]
当然,通常存在反射不安全和性能方面的警告。
答案 2 :(得分:0)
我认为,如果您使用空参数来调用copy()
,则可以使用泛型。 (在我的手机上,因此请原谅任何语法问题。)
class Person <out T: Person> {
abstract var name: String
abstract fun unchangedCopy(): T
}
data class Unemployed (
override var name: String
): Person<Unemployed>() {
override fun unchangedCopy() = copy()
}
var p:Person = Unemployed(“John”)
var q:Person = p.unchangedCopy()
这将迫使您在每个新的子类中覆盖unchangedCopy
,所以没有什么可忘记的。