2016-07-26 4 views
0

이동 둘러보기가 있습니다. 나는이 같은 https://tour.golang.org/methods/23를 해결했습니다 rot13가 정확하고 디버그 출력 바로 반환 올바른 문자열을 표시하기 전에23 번째 투어 여행에 대한 해결책이 무엇입니까?

func (old_reader rot13Reader) Read(b []byte) (int, error) { 
    const LEN int = 1024 
    tmp_bytes := make([]byte, LEN) 
    old_len, err := old_reader.r.Read(tmp_bytes) 
    if err == nil { 
     tmp_bytes = tmp_bytes[:old_len] 
     rot13(tmp_bytes) 
     return len(tmp_bytes), nil 
    } else { 
     return 0, err 
    } 
} 

func main() { 
    s := strings.NewReader("Lbh penpxrq gur pbqr!") 
    r := rot13Reader{s} 
    io.Copy(os.Stdout, &r) 
} 

. 하지만 콘솔 출력이없는 이유는 무엇입니까?

답변

3

io.Reader에 대한 Read 방법은 제공된 바이트 슬라이스에서 작동해야합니다. 새로운 슬라이스로 읽고 원본을 수정하지 않아도됩니다.

그냥 읽기 방법을 통해 b를 사용 : 당신은 결코 당신의 독자에 b을 수정하지있어

func (old_reader rot13Reader) Read(b []byte) (int, error) { 
    n, err := old_reader.r.Read(b) 
    rot13(b[:n]) 
    return n, err 
} 
+0

고마워요! 출력 매개 변수는 악합니다 ( – devmeow

+0

매개 변수로 전달하지 않으면 사전 할당 된 읽기 버퍼를 사용하기가 어렵습니다. – JimB

+0

이 코드는 올바르지 않습니다 (' 'n, err : = old_reader.r.Read (b)) '를 호출하면, 디코더는 결과를 디코드하지 않습니다. ; rot13 (b [: n]); return n, err'가 더 정확함 –

1

. io.Reader의 의미는 Read의 기능은 b의 기본 배열에 직접 데이터를 넣는 것입니다. 또한 현재 위치에서 수정을 rot13() 기능을 가정

이 작동합니다 (편집 :. 난 당신이 쉽게 변경된 내용 볼 수 있도록 버전에 가까운이 코드를 유지하기 위해 노력했습니다 JimB의 솔루션에 대한 더 관용적 솔루션입니다 이 문제) 스텁 rot13()

func (old_reader rot13Reader) Read(b []byte) (int, error) { 
    tmp_bytes := make([]byte, len(b)) 
    old_len, err := old_reader.r.Read(tmp_bytes) 
    tmp_bytes = tmp_bytes[:old_len] 
    rot13(tmp_bytes) 
    for i := range tmp_bytes { 
     b[i] = tmp_bytes[i] 
    } 
    return old_len, err 
} 

예() : 메모 측면 https://play.golang.org/p/vlbra-46zk

, 관용적 perspect로부터는 old_reader 적당한 수신기 이름 아니다 (도 old_len 인 적절한 변수 이름). Go는 짧은 수신기 이름 (이 경우 r 또는 rdr)을 선호하며 밑줄을 붙이려면 camelcase를 선호합니다 (밑줄은 실제로 golint 경고를 발령합니다).

편집 2 : 코드의 더 관용적 인 버전입니다. 동일한 동작 메커니즘을 유지하고 조금만 청소했습니다. tmp 바이트 슬라이스를 제거하고 b 직접 문제 JimB의 관용적 솔루션 결과 대상을 사용하여이에서

func (rdr rot13Reader) Read(b []byte) (int, error) { 
    tmp := make([]byte, len(b)) 
    n, err := rdr.r.Read(tmp) 
    tmp = tmp[:n] 
    rot13(tmp) 
    for i := range tmp { 
     b[i] = tmp[i] 
    } 
    return n, err 
} 

.

편집 3 : 의견에서 지적한 문제를 해결하기 위해 업데이트되었습니다.

+0

''els e' 절과 메인 코드 경로의 들여 쓰기가 포함됩니다. 여분의 슬라이스를 할당 할 필요가 없습니다. 제공된 슬라이스를 사용하십시오.복사가 필요하다면, for-loop가 아닌 바이트를 복사하기 위해'copy' 내장 함수를 사용하십시오. – JimB

+0

그래, 내가 편집에서 말했듯이, 나는 의도적으로 기능을 만들기 위해 필요한 최소한의 코드 변경을 유지하려고 노력했다. 그래서 차이점을보다 쉽게 ​​볼 수있다. 그것은 이상적으로 관용적 인 것이 아닙니다. – Kaedys

+0

이 코드는 JimB와 비슷한 문제를 가지고 있습니다 :'Read'는 n> 0과 err! = nil (예 : err = io.EOF)를 반환 할 수 있으며, 결과가 끝나면 자릅니다. –

관련 문제