是否可以创建一个扩展函数并将其称为静态?
fun System.sayByeAndExit() {
println("Goodbye!")
System.exit()
}
fun main(args: Array<String>) {
System.sayByeAndExit() // I'd like to be able to call this
}
Run Code Online (Sandbox Code Playgroud)
我理解kotlin的扩展函数是静态解析的,如Kotlin Reference(扩展函数)中所述,但这并不意味着它们可以被调用,就好像它们是类中的静态函数(在Java意义上).
我也明白这个代码不起作用,因为没有 System的实例传递给编译器将生成的方法; 因此它不会编译.
有些人可能想知道为什么这种行为是可取的.我能理解为什么你会认为不是,所以这里有一些原因:
Kotlin有办法将静态函数"挂钩"到类中吗?我很想知道.
如何调用超级的扩展功能?
例如:
open class Parent {
open fun String.print() = println(this)
}
class Child : Parent() {
override fun String.print() {
print("child says ")
super.print() // syntax error on this
}
}
Run Code Online (Sandbox Code Playgroud) 我已经创建了用于记录日志的扩展功能:
import org.slf4j.LoggerFactory
fun Any.log(msg: String) {
LoggerFactory.getLogger(javaClass.name).debug(msg)
}
Run Code Online (Sandbox Code Playgroud)
但是我不确定它是否会在任何时候被调用,因为方法LoggerFactory.getLogger调用getILoggerFactory。
MB已经有人做过类似的事情,可以向我保证不会有任何内存泄漏:)吗?
现在我使用老式的方法(在类中声明logger字段):
companion object {
private val logger = LoggerFactory.getLogger(LoggerTest::class.java.name)
}
Run Code Online (Sandbox Code Playgroud)
但是unit像这样的简单测试:
@Test
fun testLogger() {
val start = System.currentTimeMillis()
for (i in 0..999) {
log("i=" + i)
}
val end = System.currentTimeMillis()
val time = end - start
println("*** TIME=" + time.toDouble() / 1000 + " sec")
}
Run Code Online (Sandbox Code Playgroud)
显示的结果与旧时尚选项相同:
@Test
fun testLogger() {
val start = System.currentTimeMillis()
for (i in 0..999) {
logger.debug("i=" …Run Code Online (Sandbox Code Playgroud) 科特林1.2.50
我一直在youtube https://www.youtube.com/watch?v=gPH9XnvpoXE上关注本教程的一些示例.有一些我已经理解的东西,但仍然存在一些混乱.我已将评论留在下面的代码中,我不知道发生了什么.
fun main(args: Array<String>) {
val javaClient = createClient {
firstName = "joe"
lastName = "bloggs"
twitter {
handle = "@joebloggs"
}
}
println(javaClient.toConsole)
}
/* Are we passing in a lambda and receiver. What will the receiver be */
private fun JavaClientBuilder.twitter(suppler: JavaTwitterBuilder.() -> Unit) {
/* We call JavaTwitterBuilder().apply(..) Will apply return the newly created object? Not sure why we have to pass the suppler in the apply */
twitter = JavaTwitterBuilder().apply(suppler).build()
}
/* Are …Run Code Online (Sandbox Code Playgroud) 在 Kotlin 中,我有一个通用转换扩展函数,它可以简化从一种this类型的对象C到另一种类型的对象T(声明为receiver)的转换,并提供额外的转换action,该转换视为receiver原始this对象并提供对原始对象的访问:
inline fun <C, T, R> C.convertTo(receiver: T, action: T.(C) -> R) = receiver.apply {
action(this@convertTo)
}
Run Code Online (Sandbox Code Playgroud)
它的使用方式如下:
val source: Source = Source()
val result = source.convertTo(Result()) {
resultValue = it.sourceValue
// and so on...
}
Run Code Online (Sandbox Code Playgroud)
我注意到我经常在由无参数构造函数创建的函数上使用这个函数,并且认为通过创建基于其类型自动构建receivers的附加版本来进一步简化它会很好,如下所示:convertTo()receiver
inline fun <reified T, C, R> C.convertTo(action: T.(C) -> R) = with(T::class.constructors.first().call()) {
convertTo(this, action) // calling the first version of convertTo() …Run Code Online (Sandbox Code Playgroud) generics default-constructor type-constraints kotlin extension-function
在 Kotlin 语言中,这个语法有什么作用以及如何工作?
class ClassName1 {
companion object {
fun ClassName2.funName()=""
}
}
Run Code Online (Sandbox Code Playgroud) 我需要访问通用扩展函数中的类类型。例如,如果我想做一个扩展函数以返回我正在扩展的类型的成员的集合,我会这样做:
fun <T> T.getMembers() =
this::class.memberProperties
Run Code Online (Sandbox Code Playgroud)
问题是我不能在函数内部执行this :: class或T :: class。有什么方法可以访问泛型类型的类类型?
今天,我java.lang.reflect.Proxy在科特林(Kotlin)和一些人一起玩耍,对此行为感到惊讶:
import java.lang.reflect.Proxy
interface Dog {
fun bark()
fun bark3Times()
}
class DogImpl : Dog {
override fun bark() = println("Bark!")
override fun bark3Times() = repeat(3) { bark() }
}
fun Dog.bark5Times() = repeat(5) { bark() }
fun main(args: Array<String>) {
val classLoader = Dog::class.java.classLoader
val realDog: Dog = DogImpl()
val proxyDog: Dog = Proxy.newProxyInstance(
classLoader,
arrayOf(Dog::class.java)
) { _, method, _ ->
println("Proxy invoked! Method = ${method.name}")
method.invoke(realDog)
} as Dog
println("--- Dog barking 3 times ---") …Run Code Online (Sandbox Code Playgroud) 我有一个关于扩展功能的简短问题,该功能可以帮助清除一些代码。基本上,我对类名的hashCode进行了一些转换,并且我希望扩展函数执行这些转换。
例:
获得名称hashCode:StateA::class.java.name.hashCode()其中StateA是一个简单的类。
我想要扩展功能,如:
fun Class<*>.transformName(): String {
var hashString = this.javaClass.name.hashCode()
//Do my stuff on that hashString
return hashString
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用。当我使用扩展功能时StateA.transformName(),该功能给我未解析的引用带来了错误。
我尝试了各种操作,例如将函数应用于StateA::class或使hashString等于,this::class.java.name.hashCode()但无济于事。有小费吗?
我看到 Kotlin 中扩展函数的一些用法我个人认为这没有意义,但似乎有一些指导方针“显然”支持它(解释问题)。
具体来说:在类之外(但在同一个文件中)定义一个扩展函数:
data class AddressDTO(val state: State,
val zipCode: String,
val city: String,
val streetAddress: String
)
fun AddressDTO.asXyzFormat() = "${streetAddress}\n${city}\n${state.name} $zipCode"
Run Code Online (Sandbox Code Playgroud)
其中asXyzFormat()被广泛使用,并且不能被定义为专用/内部(也为情况下,可能)。
在我的常识中,如果您拥有代码 ( AddressDTO) 并且用法不是某个类/模块的本地(因此是私有/内部) - 没有理由定义扩展函数 - 只需将其定义为成员函数班级。
get-开始的函数序列化- 注释类以获得所需的行为(例如@JsonIgnore在函数上)。这个恕我直言仍然不能证明扩展功能是合理的。我对此的反驳是,官方 Kotlin 编码约定支持这种方式的扩展功能。具体来说:
自由地使用扩展函数。每次你有一个主要作用于一个对象的函数时,考虑使它成为一个接受该对象作为接收者的扩展函数。 来源
和:
特别是,当为与该类的所有客户端相关的类定义扩展函数时,请将它们放在定义类本身的同一文件中。在定义仅对特定客户端有意义的扩展函数时,将它们放在该客户端的代码旁边。不要创建文件只是为了保存“Foo 的所有扩展名”。 来源
我将感谢任何普遍接受的来源/参考解释为什么将函数移动为类的成员和/或实用参数支持这种分离更有意义。