스칼라로 t에서 옵션으로 암시 적 변환이 추가/생성 될 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1746359

  •  20-09-2019
  •  | 
  •  

문제

이것은 물건을 좀 더 효율적으로 만들 수있는 기회입니까 (Prorammer의 경우) : 나는 그것이 물건을 감싸는 것이 약간 지루하다는 것을 알았습니다. Some, 예를 들어 Some(5). 다음과 같은 것은 어떻습니까 :

implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
도움이 되었습니까?

해결책

당신은 어떤 유형의 안전을 잃고 혼란을 유발할 것입니다. 예를 들어:

  val iThinkThisIsAList = 2 
  for (i <- iThinkThisIsAList) yield { i + 1 }

나는 (어떤 이유로 든) 목록이 있다고 생각했고, 옵션 [int]로 자동 변환 되었기 때문에 반복 할 때 컴파일러에 걸리지 않았다.

나는 이것이 명시 적으로 수입 한 것이 큰 암시라고 생각한다.

다른 팁

당신은 당신이 사용할 수 있습니다 명시 적 암시 적 혼란을 피하고 동시에 코드 간결한 상태를 유지하는 패턴.

내가 의미하는 것은 명백한 암시 적으로 의미하는 바는 직접적인 전환보다는 T 에게 Option[T] 전환을 수행 할 수단을 제공하는 래퍼 객체로 변환 할 수 있습니다. T 에게 Option[T].

class Optionable[T <: AnyRef](value: T) {
  def toOption: Option[T] = if ( value == null ) None else Some(value)
}

implicit def anyRefToOptionable[T <: AnyRef](value: T) = new Optionable(value)

... 나는 그것보다 더 나은 이름을 찾을 수 있습니다 Optionable, 그러나 이제 다음과 같은 코드를 쓸 수 있습니다.

val x: String = "foo"
x.toOption // Some("foo")

val y: String = null
x.toOption // None

나는이 방법이 완전히 투명하고 서면 코드를 이해하는 데 도움이된다고 생각합니다.

참고 T <: AnyRef - 허용하는 유형에 대해서만이 암시 적 변환 만 수행해야합니다. null 정의상 참조 유형 인 값.

암시 적 전환에 대한 일반적인 지침은 다음과 같습니다.

  • 멤버를 유형에 추가 해야하는 경우 (LA "Open Classes"; 일명 "Pimp My Library"패턴) 새로운 확장되는 유형 AnyRef 그리고 필요한 회원 만 정의합니다.
  • 상속 계층 구조를 "수정"해야하는 경우. 따라서 유형이 있습니다 A 어느 가져야합니다 서브 클래스 B, 그러나 어떤 이유로 든 그렇지 않았습니다. 이 경우 암시 적 변환을 정의 할 수 있습니다. A 에게 B.

이것들은입니다 암시 적 변환을 정의하는 것이 적절한 경우. 다른 전환은 서둘러 유형 안전 및 정확성 문제로 실행됩니다.

정말 말이되지 않습니다 T 확장하려면 Option[T], 분명히 전환의 목적은 단순히 회원의 추가가 아닙니다. 따라서, 그러한 전환은 무시할 수 없을 것이다.

코드를 읽을 때 이것이 다른 개발자에게 혼란 스러울 수있는 것 같습니다.

일반적으로 보이는 것 같습니다. implicit 코드를 혼란스럽게 할 수있는 혼란스러운 캐스팅 코드를 잘라 내기 위해 한 개체에서 다른 객체로 캐스트하는 데 도움이되지만, 변수가 있고 어떻게 든 Some 그러면 그것은 귀찮은 것 같습니다.

혼란 스러울 수있는 코드를 사용하여 얼마나 혼란 스러울 지 알 수 있습니다.

메소드를 과부하하려고 시도 할 수도 있습니다.

def having(key:String) = having(key, None)

def having(key:String, default:String) = having(key, Some(default))

def having(key: String, default: Option[String]=Option.empty) : Create = {
  keys += ( (key, default) )
  this
}

원시적 t (null이 될 수 없음)에서는 효과가 없다는 점을 제외하고는 나에게 좋아 보인다. 비 전문화 된 제네릭은 항상 박스형 프리미티브를 얻는 것 같아요. 아마 괜찮을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top