Kotlin에서 정적 확장 방법을 어떻게 정의합니까? 이것도 가능합니까? 현재 아래와 같이 확장 방법이 있습니다.
public fun Uber.doMagic(context: Context) {
// ...
}
위의 확장은 인스턴스에서 호출 할 수 있습니다.
uberInstance.doMagic(context) // Instance method
그러나 아래에 표시된 것처럼 정적 방법을 어떻게 만들 수 있습니까?
Uber.doMagic(context) // Static or class method
답변
를 달성하려면 Uber.doMagic(context)
다음과 같이 컴패니언 객체 에 대한 확장을 작성할 수 있습니다 Uber
(컴패니언 객체 선언이 필요함).
class Uber {
companion object {}
}
fun Uber.Companion.doMagic(context: Context) { }
답변
공식 문서는 다음과 같습니다.
코 틀린은 패키지 레벨 함수를위한 정적 메소드를 생성합니다. Kotlin은 또한 @JvmStatic으로 해당 주석을 달면 명명 된 객체 또는 컴패니언 객체에 정의 된 함수에 대한 정적 메소드를 생성 할 수 있습니다. 예를 들면 다음과 같습니다.
class C {
companion object {
@JvmStatic fun foo() {}
fun bar() {}
}
}
이제 foo ()는 Java에서 정적이지만 bar ()는 그렇지 않습니다.
C.foo(); // works fine
C.bar(); // error: not a static method
답변
실제로 30 분 전에이 정확한 질문이 있었으므로 파고 들기 시작했고 이에 대한 해결책이나 해결책을 찾을 수 없었지만 검색하는 동안 Kotlinglang 웹 사이트 에서이 섹션 을 발견 했습니다.
확장은 널 입력 가능 리시버 유형으로 정의 될 수 있습니다. 이러한 확장은 값이 null 인 경우에도 객체 변수에서 호출 될 수 있습니다.
그래서 나는 가장 미친 아이디어를 가지고 있었지만, nullable 수신기로 확장 함수를 정의하고 (실제로 해당 수신기를 사용하지 않고) null 객체에서 호출하지 마십시오! 그래서 나는 그것을 시도했지만 꽤 잘 작동했지만 너무 못 생겼습니다. 다음과 같았습니다 :
(null as Type?).staticFunction(param1, param2)
그래서 수신기 값의 확장 파일에 null 값을 가진 val을 만든 다음 다른 클래스에서 사용하여 문제를 해결했습니다. 예를 들어 Navigation
Android 에서 클래스에 대한 “정적”확장 기능을 구현 한 방법은 다음과 같습니다. 내 NavigationExtensions.kt 파일에서 :
val SNavigation: Navigation? = null
fun Navigation?.createNavigateOnClickListener(@IdRes resId: Int, args: Bundle? = null, navOptions: NavOptions? = null,
navigationExtras: Navigator.Extras? = null) : (View) -> Unit {
//This is just implementation details, don't worry too much about them, just focus on the Navigation? part in the method declaration
return { view: View -> view.navigate(resId, args, navOptions, navigationExtras) }
}
그것을 사용하는 코드에서 :
SNavigation.createNavigateOnClickListener(R.id.action_gameWonFragment_to_gameFragment)
분명히 이것은 클래스 이름이 아니며 null 값을 갖는 클래스 유형의 변수 일뿐입니다. 이것은 변수를 작성해야하기 때문에 확장 메이커 측과 SType
실제 클래스 이름 대신 형식 을 사용해야하기 때문에 개발자 측에서는 분명히 추악 하지만 지금 당장 달성 할 수있는 가장 가까운 것입니다 실제 정적 함수와 비교합니다. Kotlin 언어 제작자들은 작성된 문제에 응답하고 해당 기능을 해당 언어로 추가하기를 바랍니다.
답변
다음과 같은 Companion 객체를 사용하여 정적 메서드를 만들 수 있습니다.
class Foo {
// ...
companion object {
public fun bar() {
// do anything
}
}
}
그런 다음 다음과 같이 호출 할 수 있습니다.
class Baz {
// ...
private fun callBar() {
Foo.bar()
}
}
답변
이 링크 를 볼 것을 권장합니다 . 보시다시피, 패키지 (파일)의 최상위에 메소드를 선언해야합니다 :
package strings
public fun joinToString(...): String { ... }
이것은
package strings;
public class JoinKt {
public static String joinToString(...) { ... }
}
constans를 사용하면 모든 것이 동일합니다. 이 선언
val UNIX_LINE_SEPARATOR = "\n"
동일하다
public static final String UNIX_LINE_SEPARATOR = "\n";
답변
또한 Kotlin에 정적 확장 메소드를 추가 할 가능성이 매우 좋습니다. 해결 방법으로 지금은 하나의 정적 확장 메소드를 사용하는 대신 여러 클래스에 exntension 메소드를 추가하고 있습니다.
class Util
fun Util.isDeviceOnline(context: Context): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connMgr.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
답변
kotlin에서 확장 메서드를 만들려면 클래스가 아닌 kotlin 파일을 만든 다음 파일에서 메서드를 선언해야합니다. 예 :
public fun String.toLowercase(){
// **this** is the string object
}
작업중인 클래스 또는 파일에서 함수를 가져 와서 사용하십시오.
