언어 및 도구들 공부 290

Go) 클로저 캡처 문제 요약

❓ 질문:for i := 0; i go func() { fmt.Println(i)}()왜 때때로 출력이 100, 100, 100... 처럼 잘못된 값이 나오는 거야?✅ 답변:이건 Go에서 클로저가 외부 변수 i를 참조하기 때문이야.go func() { ... }() 형태의 익명 함수는 반복문 변수 i를 복사하는 게 아니라 "참조"함그래서 루프가 끝난 뒤에 고루틴이 실행되면,이미 i == 100이 되어버려서 모든 고루틴이 동일한 값을 출력하게 됨이걸 "클로저 캡처 문제"라고 해❓ 질문:그럼 이걸 해결하려면 어떻게 해야 돼?✅ 답변:반복문 변수 i를 함수 매개변수로 넘겨서 "복사본"을 만들어야 해.예를 들어:for i := 0; i 이렇게 하면 i의 현재 값이 n으로 복사되어 고루틴 내부에서 안전하게 사용 ..

Go) ready 상태 channel이 복수면?

go func(){ for{ // 무한 반복 select{ case c1이 코드에서 궁금한게, c1이랑 c2가 동시에 준비되는 순간에는 어떻게 되는거야?  A.좋아, 이건 Go의 select 문이 가진 핵심적인 특징 중 하나를 짚는 아주 좋은 질문이야! 👏네 질문은 이거지:select문 안의 두 개 이상의 case가 동시에 ready일 때,즉, 예를 들어 c1 Go는 어떤 case를 실행할까?✅ 정답: 무작위(random)로 하나만 선택해서 실행해Go 언어의 select 문은 복수의 채널 연산이 동시에 가능할 때,그 중 하나를 무작위로(randomly) 선택해서 실행해.📌 공식 문서 표현 (Go spec)If multiple cases in a select are ready, one is c..

Go) Channel, select 2

package mainimport ( "fmt" "time")func main(){ c1 := make(chan int) // int 형 채널 c1 생성 go func() { for{ i:=이 코드와package mainimport ( "fmt" "time")func main(){ c1 := make(chan int) // int 형 채널 c1 생성 go func() { for{ i:=이 코드의 차이는 무엇이지?  A1.좋아! 🔥이 두 코드는 구조가 굉장히 비슷해 보이지만,세 번째 고루틴 (select 사용 부분) 에서 미묘한 차이가 있고,그게 실제 실행 흐름과 결과에 매우 큰 차이를 만들어.✅ 두 코드의 핵심 차이 요약코드select 내부 case 비교의미 코드select 내부 case 비..

Go) Channel, select

package mainimport ( "fmt" "time")func main(){ c1 := make(chan int) // int 형 채널 c1 생성 c2 := make(chan string) // string 형 채널 c2 생성 go func() { for{ i:=이 코드에서,go func(){ for{ // 무한 반복 select{ case c1이 부분에서, case를 어떻게 나눠지고 어떻게 작동되는지 잘 모르겠어.case의 조건이 어떻게 정해지는거야? case s:= ... 이 부분은, c2 채널에 값이 들어온걸 기준으로 하는거야, 값이 s일때 기준이라는거야 뭐야?    A1.좋아! 이 질문 정말 핵심적인 부분을 짚었어 💡Go의 select 문에서 case가 어떻게 작동하는지,특..

Go) 포인터 자동 역참조

You said:// 구조체 포인터?package mainimport ( "fmt" _ "fmt")type Rectangle struct { Width int Height int}func main() { var rect1 *Rectangle rect1 = new(Rectangle) // new()로 메모리 할당 후 포인터를 반환 rect2:=new (Rectangle) // new()로 메모리 할당 후 포인터를 반환 rect1.Height = 10 rect2.Height = 20 // rect2는 포인터이므로, rect2.Height로 접근 가능 fmt.Println(rect1.Height) // Output: 10 fmt.Println(rect2.Height) // Output: 20 fmt.Prin..

Go) recover()

// 패닉-리커버 함수package mainimport "fmt"func f (){ defer func(){ s:=recover() // panic이 발생하면 recover()가 호출됨 fmt.Println(s) // panic이 발생한 위치를 알 수 있음 }() // 즉시 실행 함수 꼴 panic("panic occurred") // panic 발생}func main() { f() fmt.Println("after panic") // panic이 발생해도 이 부분은 실행됨}Q1.여기에서, recover()만 하면 되는거 아니야? 왜 굳이 변수에 할당시키고 읽히게 하는거지?   A1.아주 좋은 질문이야! 👏recover()만 호출해도 panic은 "복구"되는데, 왜 굳이 s := recover() ..

Go) go.mod, go.sum

go.mod는 go init "프로젝트명"으로 작성되는 파일인가? 아니면 go mod tidy 로 작성되는 파일인가? ChatGPT의 말:좋아, 이건 Go 모듈 시스템의 핵심이야.너가 질문한 "go.mod" 파일이 어떻게 만들어지고, 어떤 명령어가 어떤 역할을 하는지 딱 정리해줄게! ✅✅ go.mod는 어떤 명령어로 만들어질까?🔹 go mod init [모듈명]👉 go.mod를 처음 생성할 때 사용하는 명령어예:go mod init my-project 결과:현재 디렉토리에 go.mod 파일이 생성됨내용은 대략 이런 형태:module my-projectgo 1.21✅ go mod tidy는 뭘 하는 명령어일까?👉 이미 있는 go.mod와 go.sum을 정리하거나, 필요한 의존성을 추가하거나 제거하는 ..

빈 식별자, blank identifier, _

data := MyStruct{A: 1, B: 2}jsonBytes1, _ := json.Marshal(data) // ✅ OKjsonBytes2, _ := json.Marshal(&data) // ✅ 이것도 OK​Q1.네가 작성해준 예시 코드, 이거 marshal한 데이터를 json byte 1, 2에 담겠다는 코드 같은데, 이때 _ 로 작성한 부분은, 원래 에러를 담는 위치이지만 에러날 일이 없을테니 그냥 버리고 쓰곘다 이 의미인가?   A1.💯 완벽하게 이해했어! 너 진짜 Go 감 잘 잡고 있다.말한 그 부분 정확하게 맞는 해석이야.✅ 코드 다시 보기jsonBytes1, _ := json.Marshal(data)여기서 _는 Go의 **“blank identifier” (빈 식별자)**라고 불..

Go) Unmarshal과 포인터

Q1.json.Unmarshal(ctx.PostBody(), &req) 이게 어떻게 진행되는지 알려줘   A1.좋아, 이 한 줄은 Go에서 JSON을 구조체로 파싱하는 핵심 라인이야.json.Unmarshal(...)이 어떤 식으로 동작하는지, 단계별로 완전 상세하게 설명해줄게! 🔍✅ 먼저 전체 코드 다시 보기json.Unmarshal(ctx.PostBody(), &req)json.Unmarshal(...) → Go 표준 라이브러리 encoding/json의 함수ctx.PostBody() → 클라이언트가 보낸 HTTP 요청 본문 (JSON 문자열, []byte 타입)&req → JSON을 여기에 파싱해서 채워줘! 라는 구조체의 주소 (포인터)🔁 동작 원리 단계별 설명1. ctx.PostBody()이건..

Go 포인터 공부 4 - 구조체 포인터로 접근하기

import "fmt"type Vertex struct { X int Y int}// 구조체 인스턴스 선언 방법var ( //① 일반적인 선언방식입니다. X가1, Y가 2로 초기화됩니다. v1 = Vertex{1, 2} //② X만 값을 지정해주고, Y는 int에 zero value로 설정됩니다. v2 = Vertex{X: 1} //③ X, Y모두 int에 zero value로 설정됩니다. v3 = Vertex{})func main() { fmt.Println("v1.X값:", v1.X) v1.X = 4 fmt.Println("v1.X = 4로 바꾼 v1.X값:", v1.X) //④ 구조체 포인터로도 구조체의 값을 바꿀 수 있습니다..