LiiNen / go-study

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

진행 0907

  • 함수 항상 call by value
  • package 밖에서 package 안에 있는 호출. 대문자로 시작
  • a, b = b, a 가능
  • golang은 컴파일 단계도 거치고 강타입언어.. ide를 쓰는게 좋다 -> 컴파일 단계에서 문제가 제거된다.
  • 첫글자 대문자는 문법. 패키지간 호출
  • 함수에서 변수명 '지정'해서 리턴해줄 때는 반환값이 '하나'더라도 괄호로 묶어줘야 한다.

~11장

  • 변수 선언 이후 사용하지 않는다면 build error가 발생한다.
    warning이 아닌, error.
  • 실수 연산 주의
    Nextafter(a, b): 1bit 차이무시용도.
    a에서 b로 1bit 만큼 이동
    math/big 이라는 패키지도 존재. 보다 정확한 연산용도. big.Float 타입
  • 변수 swap 가능
    a, b = b, a
  • 명시적 변수 return -> 코드읽기 쉽지 않을까
    함수 선언부에 return variable 선언, 함수 종료시 해당 변수들 return
  • enum 개념으로 iota
    같은 const scope 내에서 iota가 사용될 때마다, 0, 1, 2, 3, ... 값으로 사용
    iota는 같은 라인에서는 같은 값으로 취급
 const (
    a int = iota = 0 // 0으로 시작
    b int = iota = 1
    c int = iota * iota // 2 * 2 = 4
    d int = iota * iota * iota // 3 * 3 * 3 = 27
 )
  • javascript의 switch 구문은 case 안에 break를 적어주어야 하지만
    golang은 그런거 안해줘도 된다.. 좋다..
    fallthrough 쓰면 바로 다음 case문도 실행하지만 이걸 굳이 쓸까?
  • 다중 반복문에서 중첩된 반복문 한번에 탈출 가능 : Label
    권장하지는 않는다고..

12장

  • 배열 초기화 시에는 배열 크기와 함께 중괄호를 꼭 써주어야한다. (대괄호 안됨)
a := [5]int{1,2,3,4,5}
  • 단 여기서 [5]는 [...]으로 갯수 생략, 뒤의 배열 갯수로 된다.
  • 생략하는 것이기 때문에 아래와 같은 상황에서는 에러 발생
    동적할당 같은 개념이 아니라, 뒤의 갯수만큼 그대로 캐스팅되는 것으로 보임
var a [6]int = [...]int{1,2,3,4,5}
// cannot use [...]int{…} (value of type [5]int) as type [6]int in variable declaration
  • python에서처럼 -1 인덱스 참조는 불가능하다
  • C에서 변수 값을 리스트 크기로 선언하는 것은 동적할당만 가능하듯이, go도 마찬가지로 변수는 선언할 때 사용 불가
  • 하고싶다면 len(a)-1 형태로 사용
  • for loop의 iterate 같은 경우에는 python과 다르게 index, value 두개를 바탕으로 순회
for i := range a {
  fmt.Println(i)
}
// 0\n1\n2\n3\n4

for i, v := range a {
  fmt.Println(i, v)
}
// 0 1\n1 2\n2 3\n3 4\n4 5 
  • 불필요한 경우 for _, v:= range a 식으로도 사용(blank identifier)
    i, v 라고 선언해두고 i를 호출하지 않으면 에러 발생. _ 로 사용
    값을 무시하겠다는 의미로 별도의 메모리 할당을 하지 않는 것으로 보임
  • C에서는 포맷을 지정하고 포인터 개념이 들어가서
    다중배열에서 모두 탐색하지 않으면 포인터가 출력되지만
    go에서는 출력포맷을 명시하지 않게 되면 리스트를 출력함
    대충 C와 python의 중간정도 형태..

13장

  • struct 초기화 시 여러 줄 초기화
  • 마지막 줄 값 뒤에 꼭 쉼표를 달아주세요 라고 하기보단,
    마지막 값과 닫음 중괄호} 가 같은 줄에 위치하지 않으면 쉼표가 필요하다.
  • 같은 줄에 위치할 때 쉼표를 써도 vscode에서 파일 저장 시에는 자동으로 마지막 쉼표를 없애주는데,
    vi 로 그냥 파일편집해서 쉼표를 남기게된다고 하더라도 잘 수행된다.
    아래 모든 경우가 정상적으로 수행
a := A{1,2,3}
a := A{1,2
      3}
a := A{1,2
      3,}
a := A{
  1, 2, 3,
}
  • 당연히 인덱스는 안되고, 필드명으로 참조

  • 구조체 안에 구조체가 들어간 경우에도 필드명 하나로 바로 참조가 가능

  • 필드명이 겹치는 경우에는 가장 상위로 참조

  • 메모리 패딩 잘하자..

  • 구조체에서 가장 큰 크기의 변수에 맞추어서
    그 크기에 맞도록 몰아서 배치

14장

  • 포인터 구조체 사용의 경우 golang에서는 그냥 바로 참조해도됨
    283페이지 아래
  • 스택메모리 / 힙메모리 저장 위치는 코드 보고 파악

15~16장

  • 백쿼트 (`) 이용하는건 js와 유사한 점

    • 여러 줄로 문자열 묶기 가능
    • 단순히 여러 줄로 묶는 것 뿐만 아니라 \n 이 들어가는 것
    • 들여쓰기의 경우 그대로 반영이 되어, 2번째 줄부터는 inline을 모두 없애야한다.
    • \n과 같이 escape 문자를 이용해도, 그대로 출력된다
  • 단순히 여러 줄로 string을 표현하고 싶을 때, c와는 다르게 \ + {Enter}는 되지 않는다.

  • 여러 줄로 표현하고 싶으면 + 를 통해 여러 줄에 걸쳐서 더하자

    • 단, + 기호는 string 오른쪽에 붙어야한다.
    "a" + 
    "b" // "ab"
    "a"
    + "b" // 불가
    
  • 한글 등의 영어, 특수문자 이외 문자 사용시에는 string 이 아닌 rune을 이용해 파싱

  • 변수를 통한 문자열 대입의 경우 헤더 정보를 복사하는 것으로,
    값만 복사되는 것이 아닌, 참조하는 메모리 주소까지 복사된다.

  • string 자체는 불변. 중간을 임의로 변경할 수 없다
    이 불변원칙 때문에, 복제 이외에 string이 새로 생길 때마다 메모리가 계속 할당되어 메모리 낭비
    string.Builder 사용해서 합연산 하는것으로..

  • package import 에서 underscore의 사용
    https://stackoverflow.com/questions/26972615/a-use-case-for-importing-with-blank-identifier-in-golang

초기화 목적으로는 사용. 이렇게 하면 init 같은 함수는 실행된다.

0921 스터디 내용

18장 슬라이스

  • var arr []int 형태로 슬라이스 사용
  • 기본적으로는 길이 0
  • 배열과 슬라이스는 다른 개념으로, 갯수 선언하면 배열선언하는것
  • {n:m}
    • 배열과 슬라이스 모두 사용 가능한 개념
    • n번째 인덱스에 m으로 선언
    • {1, 2, 3, 2:6} 을 하면, index=2 의 값이 3과 6으로 duplicate, 에러
    • 선언되지 않은 부분은 0으로 초기화
  • make([]int, 3) : 3개짜리 int slice // 당연히 0으로 초기화
    뒷부분(360p): make([]int, 3, 6)을 하면, 3개는 0으로 초기화. 사용가능한건 6개
    make([]type, len, cap)
  • append(target, elements)
    • target 맨 뒤에 element 를 추가한 형태를 '리턴'
    • 리턴하는 것이므로 target에는 값의 변화가 없음
    • element 는 , 로 여러개를 한 번에 할 수 있지만, 타입은 맞춰야함
      즉, append(slice1, slice2)는 안됨
      뒷부분(376p): append(slice1, slice2...) 라고하면 된다. ... 붙이면 각 요솟값과 같음
    • make([]int, 3, 5) 인 상태에서 2개 이하만큼 append 하면 그 바로 뒤 공간에 넣어서 리턴
      이때 리턴된건 기존의 slice와 동일한 포인터 주소
      만약 make([]int, 3, 4) 인데, 2개 이상을 append 하면 새로운 배열을 만들어서 리턴함
      cap-len이 추가하려는 원소 수보다 작으면 새로 배열생성, 그렇지않으면 여유공간에 삽입후 리턴
  • 슬라이싱
    • 파이썬처럼 중간의 일부 원소 뽑는거와 개념은 같음
    • 다만, arr[n : m] 이라고하면
      len = m-n, cap = len(arr) - n이 된다.
      실제 값 복사는 다 안되더라도 cap의 여유공간은 그대로 가져감
    • arr[n : m : k] 라고하면
      len = m-n, cap = len(arr)-m-k 가 된다.
      arr의 k 번째 원소까지만 사용한다는 뜻
  • 포인터 관련 문제를 해결하려면, 같은 길이로 초기화하고 요소값을 복사해야함
  • copy(arr1, arr2)
    • arr1에 arr2를 복사한다
    • arr2의 len이 더 커도, arr1의 len까지만 복사함
    • arr1의 len이, arr2의 cap보다 커도 문제없음. 오히려 딱 len 까지만 복사하는 개념
    • arr2의 내용이 적어도, arr1앞부터 그냥 차례대로복사하고 끝
  • 특이하게.. 삽입과 삭제 모두 append를 이용해서함. 인덱싱 개념으로

19장 메소드

  • type myint int 해서, int와 동일한데 myint라는 이름을 가졌기에 메소드 사용가능...

20장 인터페이스

  • 메소드 오버로딩 안된다
  • 구조체 타입이 string 메소드를 갖고있으면, string에 대입해서 사용 가능: 덕타이핑
    덕 타이핑 덕분에 implements 구문을 안써도 명시적으로 인터페이스 지원이 된다
  • ? 근데, 명시하면 안되나..?
  • 인터페이스.(타입) : 구체화된 인터페이스를 다시 타입으로 변환(복원)
    리턴값은 두개. a, b := c.(d) 라고 하면
    • c가 d 로 변환된 결과가 a에
    • 변환의 성공실패여부가 b에 들어간다. // 실패시 a는 못씀
    • 런타임에러 방지. 애초에 반환 실패해도 컴파일타임 에러는 안나는데, 런타임 에러가 나기 때문에 방지책

21장 함수

  • 모든 타입은 interface{} : 빈 인터페이스 를 포함하고 있다.
  • defer는 가장 마지막에 실행하도록 하는것
    stack처럼, 가장 처음에 defer로 수행시킨 함수는 가장 나중에 실행된다.
  • defer 사용하는 신기한 예시
    https://stackoverflow.com/questions/52718143/is-golang-defer-statement-execute-before-or-after-return-statement
  • 함수 포인터
    • 리턴부에 func(param) type 이라고 쓰면
      param을 입력받아서 type을 리턴하는 '함수'를 리턴하는 함수를 작성 가능
    • func(param) type 도 별칭으로 줄일 수 있다.
      • type rfunc func (int, int) int
      • func tfunc(int) rfunc (위에서 선언된 'func(int, int) int' 를 통째로 rfunc로 축약)

About


Languages

Language:Go 100.0%