스칼라 옵션 (null)이 없음으로 예상되었지만 일부가 있습니다 (0)


답변:


17

당신은 믹싱 Intjava.lang.Integer너무

val i: java.lang.Integer = null
val o: Option[Int] = Option(i)

암시 적으로

val o: Option[Int] = Option(Integer2int(i))

이것은

val o: Option[Int] = Option(null.asInstanceOf[Int])

그러므로

val o: Option[Int] = Some(0)

로 작업하려면 java.lang.Integer다음을 작성하십시오.

val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None

2
이것은 최근 어딘가에 물었으므로 실제 문제입니다. 어쩌면 문제가 추론에 의존 Option[Integer](i).map(_.intValue)하고있을 수도 있습니다. 또한 !에 -Xlint대한 경고를 보려면를 사용 하십시오 val o.
som-snytt

복싱 왕복을 피하려면`val x : Option [Int] = Option (i) .asInstanceOf [Option [Int]]`이 ( Integer가) 추론됩니다.
som-snytt

7

이것은을 만들고 한 단계 Option로 변환 하기 때문에 발생하는 것 같습니다 Int(@MarioGalic의 답변 은 왜 이런 일이 발생하는지 설명합니다).

이것은 당신이 원하는 것을합니다 :

scala> val o: java.lang.Integer = null
o: Integer = null

scala> val i: Option[Int] = Option(o).map(_.toInt)
i: Option[Int] = None

scala> val o1: java.lang.Integer = 1
o1: Integer = 1

scala> val i1: Option[Int] = Option(o1).map(_.toInt)
i1: Option[Int] = Some(1)

다른 대답으로, 나는 제안했다 _.intValue. 전환 통화 만 저장한다고 생각합니다.
som-snytt

1

전에도 같은 문제에 직면했습니다. 이 의심스러운 행동은 스칼라 팀에 의해 알려져 있습니다. 그것을 바꾸면 다른 곳이 깨지는 것 같습니다. 참조 https://github.com/scala/bug/issues/11236https://github.com/scala/scala/pull/5176 .


2
정말로 의심스러운 행동은 null정수로 취급 됩니다. 이것은 아마도 포인터 C에 할당해도 괜찮은 곳 에서의 숙취 일 것입니다 0. 그러나 이것이 결과 포인터가임을 의미하는 것은 아니기 0때문에에서 둘 사이를 전환하는 것은 무례합니다 C.

Integer아마도 Java 코드에서 왔을 것이므로 '널을 정수로 취급하지 마십시오'는 실행 가능한 조언이 아닙니다. 그리고 우리는 명시 적으로이 정수를 사용하여 Null 허용 여부를 검사합니다 Option.apply. 따라서 안전하지 않은 작업을 명시 적으로 수행하지 않고 예기치 않은 출력이 발생합니다.
simpadjo

중요한 원인은 근본 원인이 Java 인 경우 "의심스러운 행동"에 대해 스칼라를 비난 할 수 없다는 것입니다. 실행 가능한 조언은 암시 적 변환을 사용하지 않고 Java 형식에서 동등한 스칼라 형식으로 명시 적으로 변환하는 것입니다. (따라서 JavaConverters보다는 JavaConversion)
Tim

1
글쎄, 나는이 경우 컴파일 오류 / 경고를 발생시키지 않는 Scala를 비난 할 수있다. 런타임 충돌조차 더 좋습니다. 우리 회사에서도 스칼라에서 5 년 이상의 경험을 가진 2 명의 개발자가이 문제에 부딪쳤다.
simpadjo

1
@Tim 단순히을 호출하여 런타임 충돌을 일으키는 것이 매우 쉽습니다 theInteger.intValue(). 이러한 충돌을 피하려면 추가 런타임 검사가 필요합니다. 이전 버전의 스칼라에서는이 변환으로 인해 NPE가 발생했습니다. 버그로보고되었으며 현재 동작으로 수정되었습니다. 나는 스칼라 전문가가 아니지만 역사적 맥락으로 scala-dev # 355scala # 5176 을 파헤 쳤다 .
amalloy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.