2014-02-21 5 views
2

는 예컨대 : 방법 위문자열 값을 안전하게 전달하는 방법은 무엇입니까?

def updateAsinRecords(asins:Seq[String], recordType:String) 

는 ASINs의 Seq과 레코드 유형을합니다. 둘 다 유형이 String입니다. 또한 응용 프로그램에서 String 유형으로 전달되는 다른 값이 있습니다. 말할 필요도없이, 이것은 스칼라이기 때문에, 나는 타입 시스템을 장점으로 사용하고 싶습니다. 형식 안전 방식으로 문자열 값을 전달하는 방법 (아래 참조)?

def updateAsinRecords(asins:Seq[ASIN], recordType:RecordType) 
           ^    ^
내가 이런 걸 가지고, 상상할 수

:

trait ASIN { val value:String } 

더 나은 방법이 있는지하지만 난 궁금하네요을 ...

답변

3

Value Classes and Universal Traits으로 알려진 새로운 스칼라 기능이 우수합니다. 그들은 어떤 런타임 오버 헤드를 부과하지 않습니다하지만 당신은 유형 안전한 방식으로 작동하는 데 사용할 수 있습니다 : 그들은이 목적을 위해 특별히 만들어진

class AnsiString(val inner: String) extends AnyVal 
class Record(val inner: String) extends AnyVal 

def updateAnsiRecords(ansi: Seq[AnsiString], record: Record) 

.

+0

두 음 : 1) 당신은 여전히이 경우 클래스가 될 수 있습니다, 2) 드롭 확인 추가 필드를 추가하면'AnyVal'을 확장합니다. – dhg

+0

@dhg 아니요, Value Class에는 추가 필드가있을 수 없습니다. 한 필드 만 허용됩니다. – wheaties

+0

오른쪽. 그게 내가 말한거야. :-) – dhg

3

당신은 케이스 클래스와 얇은 래퍼를 추가 할 수 있습니다

case class ASIN(asin: String) 
case class RecordType(recordType: String) 

def updateAsinRecords(asins: Seq[ASIN], recordType: RecordType) = ??? 

updateAsinRecords(Vector(ASIN("a"), ASIN("b")), RecordType("c")) 

이렇게하면 코드가 안전해질뿐만 아니라 읽기가 훨씬 쉬워집니다. 이 접근 방식의 또 다른 장점은 나중에 리팩토링하는 것이 훨씬 쉽다는 것입니다. 예를 들어 나중에 ASIN이 하나가 아닌 두 개의 필드를 가져야한다고 결정한 경우 사용 된 모든 장소 대신 ASIN 클래스 정의를 업데이트하면됩니다. 마찬가지로 필요할 때마다 이러한 유형에 메소드를 추가하는 등의 작업을 수행 할 수 있습니다.

0

유형 별명은 어떻습니까? 에 값 클래스/extends AnyVal를 사용하는 방법에 대한 제안 이외에, 당신은 아마, 어떤에만 유효 인스턴스를 아마도 이후하지 수 있도록 건설을 제어해야

+5

이것은 실제로 형식 안전하지 않습니다. ASIN이 예상되는 곳에'String'을 사용할 수 있습니다. –

3

: (서열 [ASIN] asins)

type ASIN = String 

데프 업데이트 이전 문자열은 유효한 ASIN입니다. (그리고 아마존의 것일까 요?) 어쨌든 벨이 울립니다.

이렇게하는 가장 좋은 방법은 생성자를 private으로 만들고 유효성 검사 팩토리 메서드를 컴패니언 개체에 넣는 것입니다. 그 이유는 생성자에 예외를 던지려고하면 (잘못된 인수로 인스턴스를 만들려고 할 때) 난해한 실패 모드가 생길 수 있기 때문입니다 (다른 클래스를로드하려고 할 때 종종 NoClassDefFoundError 오류로 표시됨).

그래서,뿐만 아니라 :

case class ASIN private (asin: String) extends AnyVal { /* other stuff */ } 

이 같은 것을 포함해야한다 :

object A { 
    import scala.util.{Try, Success, Failure} 

    def fromString(str: String): Try[ASIN] = 
    if (validASIN(str)) 
     Success(new ASIN(str)) 
    else 
     Failure(new InvalidArgumentException(s"Invalid ASIN string: $str") 
} 
관련 문제