[Go言語]

58137 ワード

  • GO言語の利点
  • 静的タイプ、鋼型
  • コンパイル言語
  • ごみ収集器
  • パラレル
  • マルチコア環境
  • をサポート
  • モジュール化およびパッケージングシステム
  • クイックコンパイル
  • 静的タイプ:データ型のコンパイル時に決定
    ダイナミックタイプダイナミックタイプ:ランタイムOK
    弱いタイプ:宣言値のタイプを変更できます(C言語は暗黙的に変換できます)
    強いタイプ:値自体がタイプで、タイプを変えることはできません
    コンパイル言語:
    C, C++, JAVA, C#, GO,
    エンタープライズ言語:Python、Ruby、JavaScript
    func main(){
    	// 변수 선언 예
    	var i int
    	var s string
        	
           var age int = 10
    	// 위와 같음 age := 10
    	var name string = "Maria"
        
        // var name <- 자료형을 붙이지 않으면 초기값을 대입해야함.
        
       // 병행 할당
       
    	var (
    		a1, b1	int = 30,50
    		c1, d2  string ="c", "d"
    	)
        
    変数を宣言し、使用しないとコンパイルエラーが発生します.
    これを回避するために、=に宣言された変数名
    var num int64 =1
    unsafe.Sizeof(num)//8を返し、numのバイト数
    ていすう
    	const constAge int = 999
    	const constStr string = "const stirng"
    	const canThisTo = "변수 없이도 가능!"
        	const (
    		p,q = 10,20
    	)
    Enum
    const (
    		Sun = iota +1 //= 0 +1
    		Mon		//= 1+1
    		Tues		//= 2+1
    		Wed		//= 3+1
    		Thur		//= 4+1
    		Fri
    		Sat
    		numberOfDays
    	)
    lota+aの場合、Enumではaから1番目の番号になります.
    For
    	Loop2 :
    		for i:=0; i<3 ;i++{
    			for j:= 0; j<3;j++ {
    				if j== 2{
    					// Loop 와 for문 사이에 어떠한 문법도 들어가면 안댐
    
    					break Loop2
    				}
    				fmt.Println(i,j)
    			}
    			
    		}
    
    		/*
    	for i, j := 0,0 ; i<10 ; i++, j++{
    		//error
    	}*/
    
    	for i, j := 0,0 ; i<10 ; i, j= i+1,j+2{
    		fmt.Println(i,j);
    	}
    Goto
    go言語はswitch文のcaseにbreak(書く必要はありません)を書く必要がなく、条件に合致する条件を自動的に実行してswitchを終了することができます.
    任意の場合にcaseを実行した後に次のcaseを実行したい場合は、「fallrough」を使用します.
    
    func main2(){
    	a := 1
    	
    	if a== 1{
    		goto Error1
    	}
    	if a== 2{
    		goto Error2
    	}
    	if a== 3{
    		goto Error1
    	}
    	Error1:
    		Println("Error 1")
           		 return
    		
    	Error2:
    		Println("Error 2")
    		return
    
    Error 1
    switch i {
    		//case 2, 4, 6, 8: 등의  OR 조건식으로도 표현할 수 있음.,
    		//case i>=5 && i<=10 등 조건문도 가능함
    	}
    Array
    	var a1 [5]int = [5]{1,2,3,4,5} 
            var b = [5]int {6,7,8,9,10}
    	c := [5]int{1,2,3,4,5}
        //크기 5로 지정과 초기화
        
        
        d := [...]int{1,2,3,4,5,6,7,7,123,2}
        //가변인자... 사용  크기 10 할당
    
    	//  배열 d를 e로 복사
    	e: = d
        
    シートの使用

  • シートはタイルと同じですが、長さは固定されず、動的に大きくなり、参照タイプに属します.

  • スライス値を配置するにはmake関数を使用してスペースを割り当てる必要があります.
  • make([]データ型、長さ、容量)
    	var sliceA []int =make([]int,5)
    	var sliceB = make([]int,5)
    	sliceC := make([]int,10)
        
        sliceWithInit := []int {
    		1,2,3,4,5, // 마지막 원소 뒤에 콤바 붙	여줘야함
    	}
    シート(ダイナミック割り当て)として作成された配列のappend関数のみが使用できます.
    	sliceAppendingA := []int{1,2,3}
    	sliceAppendingB := []int{4,5,6}	
    	
    	// 슬라이드의 원소를 다른 슬라이드로 append 하기 위해서 "추가될 원소를 갖은 슬라이스 배열..." 를  어팬드의 두번째 매개변수에 적어준다.
    	sliceAppendingA  = append(sliceAppendingA, sliceAppendingB...)
    スライス内の要素をコピーする場合は、copy(des,ori)関数を使用する必要があります.
    map
  • var varName map[keyType]valueType
  • make関数を使用して空間
  • を割り当てる必要がある.
    	var a map[string]int = make(map[string]int)
    	var b = make(map[string]int)
    	c := make(map[string]int)
        
        d := map[string]string {
    		"name" : "jongseo",
    		"age" : "25",
    	}
    
    宣言されたマッピングで必要なキーの値を検索
    	value, ok := d["name"]
    	Println(value,ok)
    	
    	if value, ok := d["name"] ; ok{
    		Println(value)
    	}else{
    		Println(ok)
    	}
    巡回マップ
    
    	for key,value := range d{
    		Println(key, value)
    	}
    
    n.関数
    func FUNCAME(パラメータデータ型)戻り値データ型{}
    func sum(a int, b int) (r int) {
    	r = a+b
    	return
    }
    
    func sumAndDif(a int , b int) (int, int){
    	return a+b, a-b
    }
    
    // Go 언어는 한개 이상를 반환할 수 있다.
    func main(){
    	a := sum(1,2) // a= 3
        sum, dif = sumAndDif(1,2) // 3,-1
    }
    
    可変パラメータを受信する関数の作成
    // func FUNC_NAME(Parameter_name ...data_type) return_type{}
    
    
    func multiSum(n ...int) int {
    	total := 0
    
    	for _ , value := range n {
    		total += value
    	}
    	return total
    
    }
    
    func main(){
    	total1 := multiSum(1,2,3,4,5) // 15
        slice := []int{1,2,3,4,5}
        total2 := multiSum(slice...) // 15
    }
    }
    関数を変数に保存
    func sumAndDif(a int , b int) (int, int){
    	return a+b, a-b
    }
    func main(){
    	var  varFunSum func(a int , b int) (int, int) = sumAndDif
    }
    
    変数を関数マッピングフォーマットとして保存
    mapOfVer := map[string]func(a int , b int) int {
    		"SUM" : funcName1,
    		"DIF" :	funName2,
    	}
    
    	Println(mapOfVer["SUM"](1,2))
    	
    
    匿名関数
    func(s string){
    		Println(s)
    	}("on")
        
        
    anonFunc := func(a int , b int) int {
    		return a+b 
    	    }(99,2)
    
    Println(anonFunc) // 101
    Closer
  • 関数で関数を宣言および定義したり、外部関数で宣言された変数にアクセスしたりできます.
  • Defer
    defer(遅延呼び出し)は、現在の関数が終了する前に特定の関数を実行する機能です.
    //try、finallyに似ています...
    //IO操作時に役立つdeferファイル.close();
    func hello(){
    	Println("Hello")
    }
    
    func world(){
    	Println("World")
    }
    func main(){
    	// 현재 함수 (main)이 끝나기 직전에 호출
    	defer world()
    	hello()
    	hello()
    	hello()
    Hello
    Hello
    Hello
    Wolrd
    Panic
    パラメータ
  • panic()として渡す値をrecover()の戻り値として使用します.
  • recover関数はdefer関数で記述する必要があります.
  • の実行時にエラーが発生する可能性のある関数では、recover関数を遅延関数として書くことが望ましい.
    
    func f(){
    	defer func(){
    		s := recover()
    
    		fmt.Println(s)
    	}()
    
    	panic("Error !!")
    }
    
    func main(){
    	f()
    
    	Println("Hi~");
    }
    Error !!
    Hi~
    こうぞうたい
    type Rectangle struct {
    	width, height int
    }
    func main(){
    	var rect1 Rectangle = Rectangle{10,20}
    	rect2 := Rectangle{45,65}
    	rect3 := Rectangle{width: 100, height: 200}
    }
    生成者
    goにはクラスがなく、構造体をクラスとして使用し、構造関数として構造体を作成する必要があります.
    パラメータを
  • 関数に渡し、関数内に構造体を作成し、構造体変数を作成するアドレスを返します.
  • go言語は、領域変数を参照し続けます.
    顕微鏡から離れても変数は解除されません.
  • 
    func NewRectangle(width, height int) *Rectangle {
    	newR := Rectangle{width,height}
    	return &newR
    }
    方法
    クラスがないのでメソッドもありませんが、構造体を使ってメソッドを定義する方法は
    構造体外で関数を定義するには
    
    // func(리시버명 구조체 타입) 함수명() 리턴값{}
    //리시버명 구조체 타입= 연결할 구조체 지정
    
    // Rectangle 구조체에 area메서드를 정의한다.
    func (rect *Rectangle) area() int {
    	return rect.height * rect.width;
    }
    
    func main(){
    
    	rectWithMethod := Rectangle{10,20}
    	var i  = rectWithMethod.area() // 200
    }
    
    継承
    
    
    type Person struct{
    	name string
    	age int
    }
    
    type Student struct{
    	//1. p	Person // 학생 구조체 안에 사람 구조체를 필드로 갖고 있음 , Has-a 
    	Person //2. <- ls-a 관계 , 
    	school string
    	grade int
    }
    
    func main(){
    	var s Student
    	s.name ="Jongseo"
        s.age = 25
    	s.school = "sejongUniv"
        s.grade = 4
    	fmt.Println(s)
    }
    
    {{Jongseo 25} sejongUniv 4}
    GoRoutine
    함수를 호출할때 go키워드를 붙이면, 고루틴으로 실행 ,
    고루틴으로 hello를 실행하면, main함수와 동시에 실행되기 때문에 hello()안의 출력문이 시작하기 전에 main 함수가 끝나버린다.
    */
    func main(){
    	runtime.GOMAXPROCS(runtime.NumCPU())
    	Println(runtime.GOMAXPROCS(0))
    
    	s := "Hello ,world"
    	// 클로저를 고루틴으로 실행할 때 반복문에 의해 바뀌는 변수는 반드시 매개변수로 넘겨준다.
    	// 즉 매개변수로 념겨주는 시점에 해당 변수의 값이 복사됨으로 고루틴이 생성될 때 그대로 사요할 수 있다.
    	for i:=0; i<100;i++{
    		go func(i int){
    			Println(s,i)
    		}(i)
    	}
    
    	Scanln()
    }
    Chanel
    チャネルは、高スレッド間でデータを交換し、実行フローを制御します.
    チャネル自体は値ではなくRapperタイプ
    チャンネル使用フォーマット
    make(chan DATA_TYPE)
    パラメータとしてチャネルを受信する場合
    DATA_NAME chan DATA_TYPE
    func sumWithChanel(a int, b int , c chan int){
    	c <- a+b
     }
    // 다음은 채널의 버퍼가 가득 차면 값을 꺼내서 출력함.
    func main(){
    	runtime.GOMAXPROCS(1)
    
    	done := make(chan bool,2) // 버퍼가 2개인 비동기 채널 생성
    	count := 4
    
    	// 버퍼 사이즈가 2이니까
    	// go 루틴에서 2개(0,1)을 보내고 main 반복문에서 2개(0,1)을 받아 출력한다 채널에 있떤 두개의 데이트를
    	//출력하면 버퍼는 비기 때문에 go루틴에서 다시 채널에 데이터 두개를 채운다
    
    	go func(){
    		for i:= 0 ; i<count ; i++{
    			done <- true
    			Println("고루틴 : ",i)
    
    		}
    	}()
    
    	for i := 0; i<count ;i++{
    		<-done
    		Println("main func : ",i);
    	}
    
    }*/
    // range 와 close 사용하기
    func main(){
    	c:= make(chan int)
    
    	go func(){
    		for i :=0 ; i<5; i++{
    			c<-i
    		}
    		Println("final ?")
    		close(c)
    	}()
    		//	반복문에서 range 키워드를 사용하면 채널이 닫힐 때까지 반복하면서 값을 꺼냄
    		// 여기서는 동시에 고루틴 안에 채널 c에 0부터 4까지 값을 보낸 뒤 close를 사용하여 채널을 닫는다.
    		// 이렇게 하면 range로 0부터 4까지 꺼내고 값을 출력 한 후 반복문 종료
    	for i:= range(c){
    		if i==0 {
    			// 채널이 열려있을때
    			a, ok := <-c
    			Println(a,ok)
    		}
    		Println(i)
    	}
    
    	//채널 닫혔을때
    	a, ok := <-c
    	Println(a,ok)
    
    
    }
    // 보내기 전용 및 받기 전용 채널 사용하기
    
    // chan <- DATA_TYPE : Send only
    // <- chan DATA_TYPE : Read only
    func receiveOnlySum(a, b int) <-chan int {
    	out := make(chan int)
    	go func(){
    		out <- a+b
    	}()
    
    	return out
    }
    
    // 채널만 사용해서 값 더하기
    func onlyChanelNum(a,b int) <-chan int{
    	out := make(chan int) 
    	go func(){
    		out<- a
    		out<- b
    		close(out)
    	}()
    
    	return out
    }
    
    func onlyChanelSUm(c <- chan int) <-chan int {
    	out := make(chan int)
    	go func(){
    		r:=0
    		for i:= range c{
    			r= r+i
    		}
    		out <- r
    	}()
    
    	return out
    }
    
    func main(){
    	c := onlyChanelNum(1,2)
    	out := onlyChanelSUm(c)
    
    	Println(<-out)
    }
    
    
    unc main(){
    	// 여러 채널을 손쉽게 사용할 수 있도록 select문 제공
    	
    	intChanel:= make(chan int)
    	stringChanel:= make(chan string)
    
    	go func(){
    		for{ // 무한루프
    			 intChanel <- 10
    			 time.Sleep(100 * time.Millisecond)
    		}
    	}()
    
    	go func(){
    		for {
    			stringChanel <- "Hello, world"
    			time.Sleep(time.Millisecond * 500)
    		}
    	}()
    
    	go func(){
    		for {
    			select {
    				// case <- 채널1:
    				case i := <- intChanel:
    					Println("int Chanel : ",i)
    
    				case s := <- stringChanel:
    					Println("string Chanel : ", s)
    					
    				case <-time.After(50*time.Millisecond):
    					Println("Time out")
    			}
    		}
    	}()
    
    	time.Sleep(10 * time.Second)
    }
    string Chanel : Hello, world
    int Chanel : 10
    Time out
    Time out
    int Chanel : 10
    Time out
    int Chanel : 10
    Time out
    int Chanel : 10
    Time out
    int Chanel : 10
    Time out
    ...