경로 의존 유형의 빠른 해석
11153 단어 scalaprogrammingtutorialc
경로 의존 형식은 실행할 때만 알 수 있는 형식을 처리하는 데 매우 유용합니다.
C. 시간 및 경로 관련 유형
최근에 저는 Scala와 C가 상호작용을 하도록 코드를 작성해 왔습니다. 이렇게 해서 저는 독특한 도전에 부딪혔습니다.그 중 하나는 사용자가 필요할 때 C 귀속에서 사용할 수 있도록 유형을 정의하는 것이다.
time_t
는 c표준 라이브러리의 일부이지만 그 실현은 이 라이브러리를 실현하는 라이브러리에서 이루어진다.i386 리눅스(i386은 32비트 Intel arch) 기기에서 time_t
는 JVMtime_t
에 해당하고, i386 Midnight BSD에서는 JVMLong
에 해당한다.내 라이브러리의 C 바인딩은 유형을 기반으로 하기 때문에 심각한 문제가 있습니다.Int
를 time_t
로 정의한다면 나의 라이브러리는 자정 BSD 기계type time_t=Int
를 time_t
로 정의한다면 제 라이브러리는 Linux 기기에서만 사용할 수 있습니다type time_t=Long
과time64_t
를 정의한다면 나의 라이브러리는 이 두 운영체제에서 모두 사용할 수 있지만 사용자 코드가 한 운영체제에 잠겨서 그들은 어떤 운영체제를 개발할지 걱정할 수밖에 없다.type time_t = if os == Linux then Long
else if os == MidnightBSD then Int
else Nothing
그럼 난 괜찮아!!프로그램이 실행될 때 경로에 따라 정의된 형식을 쓸 수 있는 방법이 있다면...읊다, 읊조리다경로 의존 유형!!
일이 순조롭게 진행되도록 하다
나는 나의 사용자를 만족시킬 수 있는 몇 가지 특징이 있다.우선, 나는
time_t
의 원형이 필요하다.trait time_t_proto:
type time_t
val time_t_integral: Integral[time_t]
implicit class time_t_ops(time_t: time_t)
extends time_t_integral.IntegralOps(time_t)
implicit class time_t_ord(time_t: time_t)
extends time_t_integral.OrderingOps(time_t)
Scala는 컴파일할 때 time_t
이 버전을 사용할 것입니다. 이 버전에서는 time_t
형식 클래스를 실행할 때 time_t
정의하기로 약속합니다.그리고 우리는 컴파일러가 Integral
와 time_t
스텔스 클래스를 통해 +
연산자나 <
연산자 등의 기능을 확장time_t_ops
하는 방법을 알려준다.이것은 사용자가 이 유형에 대해 기본 정렬과 산술을 할 수 있도록 합니다. time_t_ord
또는 Int
처럼, 컴파일할 때 형식이 알 수 없지만.이제 구현이 필요합니다.
trait time_t_impl[U](using val time_t_integral: Integral[U])
extends time_t_proto:
type time_t = U
이것은 실현된 것 같지는 않지만, 이렇게 작성된 것이기 때문에, 대형적인arch에 특정된Long
유형에 혼합할 수 있다.trait Platform extends time_t_proto
object PlatformI386 extends Platform, time_t_impl[Int]
object PlatformX64 extends Platform, time_t_impl[Long]
val platform: Platform = if arch == i386 then PlatformI386
else if arch == x86_64 then PlatformX64
else ???
우리는 마침내 최종 결과를 얻었다.Platform
와impl에 사용되는 디자인은 이 원형의 여러 개와 플랫폼에 특정한 C 유형(예를 들어 time_t_proto
에 사용되는impl 유형을 허용한다.또한 수많은 컴퓨팅 플랫폼에 귀속을 신속하고 쉽게 정의할 수 있습니다.마지막으로 실행할 때 적당한 dev_t
구현을 선택하고 이를 Platform
값에 분배함으로써 사용자가 플랫폼에 특정한 유형을 사용할 수 있고 플랫폼에 특정한 방식으로 쓸 필요가 없다.결과적으로 사용자는 바인딩을 다음과 같이 정의할 수 있습니다.
import platform.time_t
def time(timer: Ptr[time_t]): time_t = bind
어느 컴퓨터에 접근하든지 간에 이러한 귀속은 작동할 것이다. 왜냐하면 적절하고 경로에 의존하는 유형 정보는 실행할 때 불러오고 사용되며, 컴파일링할 때 컴파일러에게 완전한 유형 안전을 확보하기 위해 충분한 정보와 보장을 제공하기 때문이다.물론 사용자가 원한다면 플랫폼에 특정한 코드를 작성할 수 있다.
import PlatformX64.time_t
def time(timer: Ptr[time_t]): time_t = bind
위 코드는 잘 작동하고 있습니다. 위 코드의time t는 알 수 없는 형식이 아니라 컴파일할 때platform
로 이해됩니다.그러나 이 코드는 더 이상 어디에도 적용되지 않을 것이며 이것은 JVM을 위해 코드를 작성하는 데 큰 매력이 될 것이다.이것은 범형을 통해 실현할 수 있습니까?
요컨대, 없다. 우리는 같은 작업량으로 범형을 사용해서 같은 효과를 낼 수 없다.우리는 범형으로 상술한 기능을 실현하려고 시도할 수 있지만, 범형은 우리를 실패하게 할 것이다.proto trait 및 Platform trait를 수정하여 삽입식 대신 일반형
Long
을 사용한다고 가정합니다.trait time_t_proto[time_t]:
val time_t_integral: Integral[time_t]
implicit class time_t_ops(time_t: time_t)
extends time_t_integral.IntegralOps(time_t)
implicit class time_t_ord(time_t: time_t)
extends time_t_integral.OrderingOps(time_t)
trait time_t_impl[U](using val time_t_integral: Integral[U])
extends time_t_proto[U]
trait Platform[A] extends time_t_proto[A]
object PlatformI386 extends Platform[Int], time_t_impl[Int]
object PlatformX64 extends Platform[Long], time_t_impl[Long]
val platform: Platform[?] = if arch == i386 then PlatformI386
else if arch == x86_64 then PlatformX64
else ???
위의 코드는 틀림없이 컴파일될 것입니다. 그러나 사용자는 어떻게 type time_t
유형을 얻을 수 있습니까?이곳의 time_t
유형은 정확한 유형에 대응하지만, 우리 사용자에게는 사용할 수 없습니다.더 심각한 것은 우리의 코드가 더욱 복잡해졌다는 것이다. ?
진정으로 우리가 원하는 방식으로 일을 하기 위해서는 많은 일을 해야만 C와 연결된 모든 부분을 관리하는 god의 대상이 될 수 있다.요컨대
경로 의존 유형은 Scala의 강력한 기능이지만 지역사회에서 잘 이해되지 않는다.나는 플랫폼의 특정 유형(예를 들어 C
Platform
)의 문제가 경로 의존 유형의 필요성과 그들이 어떤 상황에서 범주형을 어떻게 초월하는지 설명하기 쉽다고 믿는다.
Reference
이 문제에 관하여(경로 의존 유형의 빠른 해석), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/markehammons/a-quick-explanation-of-path-dependent-types-4pki텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)