Skip to content

Instantly share code, notes, and snippets.

@mikehearn
Created December 18, 2015 13:46
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mikehearn/0313f4a2751f6929e8d7 to your computer and use it in GitHub Desktop.
Save mikehearn/0313f4a2751f6929e8d7 to your computer and use it in GitHub Desktop.
Kotlin duck typing / type classing fiddle
class A {
fun shout() = println("go team A!")
}
class B {
fun shout() = println("go team B!")
}
interface Shoutable {
fun shout()
}
class InvokeHandler(private val underlying: Any) : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
for (fn in underlying.javaClass.methods) {
if (fn.name == method.name && Arrays.equals(fn.parameterTypes, method.parameterTypes)) {
if (args == null)
return fn.invoke(underlying)
else
return fn.invoke(underlying, *args)
}
}
throw UnsupportedOperationException("$method with $args")
}
}
inline fun <reified T> Any.dynamicCast(): T {
return Proxy.newProxyInstance(javaClass.classLoader, arrayOf(T::class.java), InvokeHandler(this)) as T
}
fun main(args: Array<String>) {
val a = A()
val b = B()
val sa = a.dynamicCast<Shoutable>()
val sb = b.dynamicCast<Shoutable>()
sa.shout()
sb.shout()
}
@stangls
Copy link

stangls commented Apr 13, 2017

Hello,
maybe you want to take a look at my project for static ducktyping in Kotlin (like Go has):
https://github.com/stangls/DucKtypes/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment