2017-11-14 12 views
1

나는이 중복 알고 있지만 여기에 걸쳐 anwser은 단순히 나를 만족하지 않습니다 내가 지적하고 무엇을 나에게 불분명 남아 있었다 몇 가지에 대해 이야기하고 싶습니다유효하지 않은 함수 입력시 정의되지 않은 함수를 반환하거나 오류를 발생합니까?

JS library best practice: Return undefined or throw error on bad function input?

.

먼저 개인적으로 오히려 오류를 던지고 undefined를 반환하는 예제를 제시하고자합니다.

function sum(a, b) 

소비자가 입력 상자의 직접 값을 전달했기 때문에 소비자가 문자열을 전달하고 최종 사용자가 숫자가 아닌 다른 형식으로 입력했다고 가정 해 보겠습니다.

저자가 sum의 문자열 입력시 정의되지 않은 문자를 반환했다면, 개발자가 어느 시점에서 문자열을 입력 했더라도 아무 일도 일어나지 않았으며 예상했던대로 그 사람이 신경 쓰지 않았을 것입니다. 그러나이 경우에는 오류가 발생했기 때문에 개발자는 사실상 처리해야 할 최악의 경우임을 깨닫게되었을 것입니다. 왜냐하면 결국 아무도 프로그램에서 오류를 원하지 않기 때문입니다.

그래서 기본적으로, devs는 실제로 오류를 던져서 엣지 케이스를 인식하지 못하게합니까?

이 꽤 많이있는 위에서 언급 한 문제에 코멘트이었다 내가 요구하고 정확히하지만 아무도 아직 대답하지 :

"하지만 1 개의 여분 분을 소요하기 때문에 나 오류가 발생 대신하는 조용히 죽어 버리면 문서를 읽을 시간이 없던 사람들을위한 디버깅 시간을 절약 할 수 있을까요? "

위에서 허용 anwser에 또 다른 점 :

"예외를 잡는 것은 오류가 일반적으로 발생하는 경우 있도록 반환 값을 테스트보다 훨씬 느린, 다음 예외가있을 것 많이 느려. "

이 qoute를 적용 할 수있는 유일한 경우는 입력이 항상 올바른 형식으로되어있는 I/O 또는 네트워크 물건입니다. 사용자가 해당 ID로 존재하지 않습니다.

그런 경우에는 왜 오류가 발생하면 프로세스가 느려지는지 이해합니다. 그러나 순수하고 동기 함수로만 구성된 수학 라이브러리는 무엇입니까?

출력을 확인하는 대신 입력을 확인하는 것이 더 스마트하지 않습니까? (입력이 함수를 실행하는 대신 작동하는지 확인하고 정의되지 않은 값이 반환되는지 확인하십시오.)

실제로 C# 세계에서 왔기 때문에 실제로 많은 유형의 검사가 이루어 지므로 라이브러리를 사용해야한다고 생각합니다. 그 길은 자비 롭고 어쨌든 일하기보다는 오히려 의도 한 바대로.

답변

2

저는 OO 언어의 경우 나쁜 사례 라해도 null을 반환하는 것이 일반적이며 null을 발명 한 사람은 billion dollar mistake이라고 주장합니다.

Maybe 형식을 사용하여 OO가 존재하기 전에 기능 언어가이 문제를 해결했습니다.

함수를 작성할 때 성공 또는 실패가 포함 된 변형을 사용할 수 있습니다. Scott Wlaschin은 railway orientated programming을 호출하고 약속은 일종의 철도 지향 프로그래밍입니다.

OO에서 Maybe를 사용할 때의 문제점은 union types이 없다는 것입니다. F에서 # 코드는 다음과 같이 보일 것이다 : F 번호에 뭔가를 일치하면이 경우를 잊어 버린 경우 당신이 컴파일 시간 오류가 발생합니다

let x = 
    // 9/0 throws so divideBy returns None the caller of divideBy can 
    //decide what to do this this. 
    match (divideBy 9 0) with 
    | Some result -> //process result 
    | None -> //handle this case 

합니다 (None을 처리하지). OO에서는 런타임 오류가 발생하거나 조용히 실패하지 않습니다. nullable 형식에 액세스하려고 시도 할 때 컴파일러에서 C#의 개선 사항이 나타날 수 있지만 if not null 만 처리하면 사용자가 다른 형식을 제공하도록 강요하지 않습니다.

JavaScript에서는 약속을 사용하거나 결과 개체를 반환하는 것이 좋습니다. 약속은 최신 브라우저 및 노드에 기본입니다. 브라우저에서 실패한 약속을 처리하지 않으면 콘솔에서 소리 치게됩니다 (콘솔의 오류 및 소스의 잡히지 않는 거부시 중단). 미래에; nodejs; 처리되지 않은 예외로 인해 프로세스가 중지됩니다.

//example with promises 
const processNumber = compose([ 
    //assuming divideBy returns a promise that is rejected when dividing by zero 
    divideBy(9) 
    ,plus(1) 
    ,minus(2) 
    ,toString 
]) 
// 9/0 returns rejected promise so plus,minus and toString are never executed 
processNumber(0) 
.then(
    success => //do something with the success value 
    ,fail => //do something with the failure 
); 

//example of result type: 
const Success = {} 
,Failure = {} 
,result = (type) => (value) => 
    (type === Failure) 
    //Failure type should throw when trying to get a value out of it 
    ? Object.create({type:type,error:value}, { 
     value: { 
     configurable: false, 
     get: function() { 
      throw "Cannot get value from Failure type" 
     } 
     } 
    }) 
    : ({ 
     type:type 
     ,value:value  
    }) 
; 
//convert a function (T->T) to (result T->result T) 
const lift = fn => arg => { 
    //do not call funcion if argument is of type Failure 
    if(arg.type === Failure){ 
    return arg; 
    } 
    try { 
    const r = fn(arg.value); 
    //return a success result 
    return result(Success)(r); 
    } catch (e) { 
    //return a failure result 
    return result(Failure)(e); 
    } 
}; 
//takes a result and returns a result 
const processNumber = compose(
    [ 
    //assuming divideBy throws error when dividing by zero 
    divideBy(9) 
    ,plus(1) 
    ,minus(2) 
    ,toString 
    ].map(//lift (T->T) to (result T -> result T) 
    x => lift(x) 
) 
); 

const r = processNumber(result(Success)(0));//returns result of type Failure 
if(r.type === Failure){ 
    //handle failure 
} else { 
    //handle r.value 
} 

당신은 단지 null을 반환 또는 OO에서하지만 점점 더 많은 사람들이 그 일을 처리 할 수 ​​not the best way있어 실현하기 위해 시작 던질 수있다. 던지기는 부작용이므로 함수를 불순하게 만듭니다 (불순한 함수는 코드를 유지하는 것이 어렵습니다).

Null은 실패 할 수있는 함수를 반영하기에 좋지 않습니다. 예상 된 형식을 반환하지 못한 이유를 알지 못하고 이유를 가정해야합니다. 코드에서 가정을하면 코드를 유지 관리하기가 더 어려워집니다.

+0

약속이 진지하게 수학 기능 등과 같이 지나치게 과장 해있는 시간은 어떨까요? 또한 C#의 maybes는 멋지게 보입니다. 나는 그들이 단지 – ThatBrianDude

+0

@ ThatBrianDude를 잡았 으면 좋겠다. Java에서 C#은 null이 반환되면 무언가 잘못되었다는 것을 나타내는 데 사용될 수 있고 예외를 throw하면 무엇이 잘못되었는지를 나타낼 수있다. 자바 스크립트에서 동기 함수에 대한 결과 유형을 반환하는 것이 더 좋다고 생각합니다. 'Maybe'와 유사하지만 'Some'및 'None' 대신'Success '및'Failure '가 있으며'Success '는 실제 값입니다. 'Failure'는 오류입니다. js 예제는 https://github.com/amsterdamharu/lib/blob/master/src/index.js#L36-L125에서 작업하지만 내일이나 그 후에 완료해야합니다. – HMR