20210106のGoに関する記事は10件です。

Goのエラー処理について ※雑な記事です。

Goには例外機構がないが、関数が複数の戻り値を返すことができる特徴を生かして以下のようなエラー処理を実装できます。

    result, err := method()
    if err != nil {
        //エラー処理
        log.Fatal(err)
    }

「へえ、そうなんだ。とりあえずエラー処理はこう書けばいいんだ。」
この程度の理解度で問題ない気がしますが、なんとなく気になったのでまとめてみます。(※結局まとまりませんでした。)

そもそも例外機構ってなに?

実務で使用しているVB.NETでは例外処理は以下のように実装します。

try {
  処理
} catch ( 例外のクラス 変数 ) {
  例外処理
} finally{
 後処理
}

例外機構ってなに?とか書いたけど、構文に当てはめればエラー処理を実装できますよってだけですね。その構文がGoには存在しません。
エラーハンドリングできないとか致命的じゃん!!となりますが、そんなことはなくGoでもエラー処理は実装できます。その一つが最初に記載したもので、2つ目の変数でエラーの有無を判断します。これはイディオム(英語の熟語のようなもの)なので、やっぱり「へえ、そうなんだ」くらいでいいのかもしれませんね。

実際に動かしてみてみた

以下のコードはmain.goと同じ階層にあるfoo.txtを読み込み専用で開く処理をします。

main.go
package main

import (
    "log"
    "os"
)

func main() {
    f, err := os.Open("foo.txt")
    if err != nil {
        log.Fatal("err")
    }
    log.Fatal("ok")
    defer f.Close()
}

ファイル名をhoge.txtに変更してエラーになるとき、 err に何が入っているのか確認してみました。

image.png

、、、とりあえずエラーのときはnil以外が入ると覚えておけば大丈夫そう。関数が返す2つ目の戻り値は常にエラーに関する情報ってことでOKなのかな??

まとめ

まとまりませんでした。
とりあえず、「へえ、そうなんだ。とりあえずエラー処理はこう書けばいいんだ。」で明日以降も過ごしていきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

golangでmultipart.File型の画像をリサイズ〜S3にアップロードするまで

概要

golang製のAPIサーバーを個人開発する中で、フロント側から受け取った画像ファイルをリサイズ等編集して、S3にアップロードするロジックを実装しました。その際、結構苦戦したので、要点をまとめていきたいと思います。

実践

multipart/form-dataをパース

file, _, err := r.FormFile("image")

fileにmultipart.File型としてgoで扱えるようになります。

バッファーに内容を流し込む

img := &models.Image{
        UserID: uid,
        Buf:    &bytes.Buffer{},
    }

    _, err := img.Buf.ReadFrom(file)
    if err != nil {
        return &models.Image{}, err
    }

今回のアプリはレイヤードアーキテクチャ+DDDを採用しているので、Imageモデルをポインタ型で宣言して、参照渡しでバッファーにデータを流し込んでます。この時バッファーを格納するBufも宣言してあげないと、アドレス領域が確保されずnilエラーが発生してしまうので、注意が必要です。

画像編集

func ResizeImage(i *models.Image) error {
img, t, err := image.Decode(i.Buf)
    if err != nil {
        return err
    }

省略

err = jpeg.Encode(i.Buf, m, nil)
        if err != nil {
            return err
        }

バッファー型にすればデコード・エンコード可能になるので、ここでリサイズ等画像編集する。

S3にアップロード

uploader := s3manager.NewUploader(sess)
        _, err = uploader.Upload(&s3manager.UploadInput{
            Bucket: aws.String("example"),
            Key:    aws.String(img.Name),
            Body:   img.Buf,
        })

バッファー型のままアップロード可能なので、対象のバケット、名前等定義すれば完了!!

参考資料

Goでmultipart/form-dataをparseする
AWS SDK for Go S3バケット基本操作
リアルタイム画像リサイズAPIをGo + Serverless Application Modelで作った時の感想

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Using cgo with the go command

Using cgo with the go command

Cのコードが認識されない

c.go
// #include <stdlib.h>
import "C"

//とimportの間に空行が入ってると前文(preamble)として認識されないようだ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

goでCする

c.go
// #include <stdlib.h>
import "C"

//とimportの間に空行入ってると全文として認識されないようだ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語-基本❷

基本❷

プログラミング基本からGoの理解を文字におこして行こうと思います!
Go言語-基本❶はこちら

変数定義と代入の違い

package main
func main(){
  n := 100
  n := 200
  println(n)
}

//コンソール
:=の左側に新しい変数がないとエラーになる

変数定義の「:=」と、代入の「=」の違いに注意
2度変数nを定義しているためエラー

変数が使える場所

package main
func main(){
  println(n) //使用不可
  n := 100
  println(n) //使用可能
}

//コンソール
変数nが定義されていないとエラー

変数は、定義したあとでしか使えない
コンソールには、「変数nが定義されていない」ことを表すエラー

使わない変数

package main
func main(){
  a := 100
  b := 200 //使用していない
  println(a)
}

//コンソール
変数bが使用されていないとエラー

定義したものの使っていない変数があるとエラー
Goではエラーを発生させて、バグを未然に防ぐ設計になっている

型の不一致

package main
func main(){
  n := 100
  n := "Go" //int型でない
  println(n)
}

//コンソール
string型の"Go"をint型として変数nに代入できないとエラー

変数のデータ型と異なるデータ型の値は代入できない

変数の演算

package main
func main(){
  n := 100
  println(n + 100)
}

//コンソール
200

変数は値と同じように扱える

自己代入

package main
func main(){
  n := 100
  n = n + 10 //100+10の合計を変数nに再代入
  println(n)
}

//コンソール
110

nの値である100に数値の10を足して、それを再度nに代入(自己代入)

自己代入の省略

//原型            //省略型
n = n + 10       n += 10
n = n - 10       n -= 10
n = n * 10       n *= 10
n = n / 10       n /= 10
n = n % 10       n %= 10
}

「n = n + 10」は「n += 10」と省略でき、これは「-」「*」「/」「%」でも同様

自己代入の省略(2)

n = n + 1  n += 1  n++
n = n - 1  n -= 1  n--
}

「++」という記号は「変数に1を足す」という意味
反対に「--」は「変数から1を引く」という意味

変数に1足す、1引く時のみ、さらに省略できる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Goの基本❷

Goの基本

プログラミング基本からGoの理解を文字におこして行こうと思います!
Goの基本❶はこちら

変数定義と代入の違い

package main
func main(){
  n := 100
  n := 200
  println(n)
}

//コンソール
:=の左側に新しい変数がないとエラーになる

変数定義の「:=」と、代入の「=」の違いに注意
2度変数nを定義しているためエラー

変数が使える場所

package main
func main(){
  println(n) //使用不可
  n := 100
  println(n) //使用可能
}

//コンソール
変数nが定義されていないとエラー

変数は、定義したあとでしか使えない
コンソールには、「変数nが定義されていない」ことを表すエラー

使わない変数

package main
func main(){
  a := 100
  b := 200 //使用していない
  println(a)
}

//コンソール
変数bが使用されていないとエラー

定義したものの使っていない変数があるとエラー
Goではエラーを発生させて、バグを未然に防ぐ設計になっている

型の不一致

package main
func main(){
  n := 100
  n := "Go" //int型でない
  println(n)
}

//コンソール
string型の"Go"をint型として変数nに代入できないとエラー

変数のデータ型と異なるデータ型の値は代入できない

変数の演算

package main
func main(){
  n := 100
  println(n + 100)
}

//コンソール
200

変数は値と同じように扱える

自己代入

package main
func main(){
  n := 100
  n = n + 10 //100+10の合計を変数nに再代入
  println(n)
}

//コンソール
110

nの値である100に数値の10を足して、それを再度nに代入(自己代入)

自己代入の省略

//原型            //省略型
n = n + 10       n += 10
n = n - 10       n -= 10
n = n * 10       n *= 10
n = n / 10       n /= 10
n = n % 10       n %= 10
}

「n = n + 10」は「n += 10」と省略でき、これは「-」「*」「/」「%」でも同様

自己代入の省略(2)

n = n + 1  n += 1  n++
n = n - 1  n -= 1  n--
}

「++」という記号は「変数に1を足す」という意味
反対に「--」は「変数から1を引く」という意味

変数に1足す、1引く時のみ、さらに省略できる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語の基本❷

Goの基本

プログラミング基本からGoの理解を文字におこして行こうと思います!
Go言語の基本❶はこちら

変数定義と代入の違い

package main
func main(){
  n := 100
  n := 200
  println(n)
}

//コンソール
:=の左側に新しい変数がないとエラーになる

変数定義の「:=」と、代入の「=」の違いに注意
2度変数nを定義しているためエラー

変数が使える場所

package main
func main(){
  println(n) //使用不可
  n := 100
  println(n) //使用可能
}

//コンソール
変数nが定義されていないとエラー

変数は、定義したあとでしか使えない
コンソールには、「変数nが定義されていない」ことを表すエラー

使わない変数

package main
func main(){
  a := 100
  b := 200 //使用していない
  println(a)
}

//コンソール
変数bが使用されていないとエラー

定義したものの使っていない変数があるとエラー
Goではエラーを発生させて、バグを未然に防ぐ設計になっている

型の不一致

package main
func main(){
  n := 100
  n := "Go" //int型でない
  println(n)
}

//コンソール
string型の"Go"をint型として変数nに代入できないとエラー

変数のデータ型と異なるデータ型の値は代入できない

変数の演算

package main
func main(){
  n := 100
  println(n + 100)
}

//コンソール
200

変数は値と同じように扱える

自己代入

package main
func main(){
  n := 100
  n = n + 10 //100+10の合計を変数nに再代入
  println(n)
}

//コンソール
110

nの値である100に数値の10を足して、それを再度nに代入(自己代入)

自己代入の省略

//原型            //省略型
n = n + 10       n += 10
n = n - 10       n -= 10
n = n * 10       n *= 10
n = n / 10       n /= 10
n = n % 10       n %= 10
}

「n = n + 10」は「n += 10」と省略でき、これは「-」「*」「/」「%」でも同様

自己代入の省略(2)

n = n + 1  n += 1  n++
n = n - 1  n -= 1  n--
}

「++」という記号は「変数に1を足す」という意味
反対に「--」は「変数から1を引く」という意味

変数に1足す、1引く時のみ、さらに省略できる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語の基本❶

Goの基本

プログラミング基本からGoの理解を文字におこして行こうと思います!

文字列とは

package main
func main(){
  println("Hello, Go")
}

""(ダブルクォーテーション)で囲んでいないとエラーが発生する

出力の命令

package main
func main(){
  println("Hello, Go")
}

//コンソール
Hello, Go

printlnというのは、Goが用意している「命令」の1つ

「コンソールにprintln()の中のものを出力せよ」という命令
→コンピュータが文字列をコンソールに出力

プログラムの構成

package main
func main(){
  println("Hello, Go")
}

Goのコードのファイルは、パッケージ定義部や関数定義部によって構成

ここでは「package main」と書かれたファイルの、main関数の{ }の中に命令を書くと
それが順に実行される

数値を使う

package main
func main(){
  println(1)
  println(1 + 1)
  println(1 - 2)
  println("1 - 2")
}

//コンソール
1
2
-1
1 - 2

数値は文字列と違いダブルクォーテーションで囲まない

演算を行う

package main
func main(){
  println(2 * 5) //掛け算
  println(6 / 2) //割り算
  println(9 % 2) //余りを出す
}

//コンソール
10
3
1

このような演算に用いる記号を「演算子」
演算子の種類はプログラミング言語によって異なる

文字列の連結

package main
func main(){
  println("Hi" + "Go")
  println("1" + "2")
}

//コンソール
Hi,Go
12

文字列に対して「+」を使用すると1つの文字列にする

変数とは

データ(値)をいれておく箱
箱(変数)には名前(変数名)がついていて名前を用いて変数から値を取り出せる

変数とデータ型

var number int 
//number(変数名)、int(データ型)
var number string 
//number(変数名)、string(データ型)

変数を利用するには、まず変数を定義
「var 変数名 データ型」

コンピュータに変数を作ることを指示

データ型

"Hello, Go" //文字列(string型)
3 //整数(int型)

文字列や数値は「データ型」と呼ばれる

変数を使う

package main
func main(){
  var n int //変数nの定義
  n = 100 //変数nに100を入れる(代入する)命令
  println(n) //nを使用し100を出力
}

//コンソール
100

「=」は、変数という箱に値を入れるための記号

定義と代入

package main
func main(){
  var n int = 100
  println(n) 
}

//コンソール
100

「var n int = 100」と書けば、変数の定義と代入を同時に行える

package main

func main() {
    var message string = "Hello, 世界" //変数messageを定義して代入
    println(message)
}

変数の値の更新

package main
func main(){
  var n int = 100
  println(n)
  n = 200
  println(n)
}

//コンソール
100
200

変数は何度でも上書きできる

データ型の省略

package main
func main(){
  var n = 100
  println(n)
}

//コンソール
100

「var n int = 100」のように、変数定義と値の代入を同時に行う場合
データ型の指定を省略できる

Goがint型であることを代入される値から判断しているから

変数定義の省略

package main
func main(){
  n := 100
  println(n)
}

//コンソール
100

「var n int = 100」と同じ意味
「:=」であることに注意

printlnの便利な書き方

package main
func main(){
  a := 100
  b := 200
  println(a,b)
}

//コンソール
100 200

printlnの()内に変数aとbをコンマで区切って並べて書けば
2つの値を同時に出力できる

コンマは出力されず、スペースで区切られて1行で表示

Go言語の基本❷はこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語-基本❶

基本❶

プログラミング基本からGoの理解を文字におこして行こうと思います!

文字列とは

package main
func main(){
  println("Hello, Go")
}

""(ダブルクォーテーション)で囲んでいないとエラーが発生する

出力の命令

package main
func main(){
  println("Hello, Go")
}

//コンソール
Hello, Go

printlnというのは、Goが用意している「命令」の1つ

「コンソールにprintln()の中のものを出力せよ」という命令
→コンピュータが文字列をコンソールに出力

プログラムの構成

package main
func main(){
  println("Hello, Go")
}

Goのコードのファイルは、パッケージ定義部や関数定義部によって構成

ここでは「package main」と書かれたファイルの、main関数の{ }の中に命令を書くと
それが順に実行される

数値を使う

package main
func main(){
  println(1)
  println(1 + 1)
  println(1 - 2)
  println("1 - 2")
}

//コンソール
1
2
-1
1 - 2

数値は文字列と違いダブルクォーテーションで囲まない

演算を行う

package main
func main(){
  println(2 * 5) //掛け算
  println(6 / 2) //割り算
  println(9 % 2) //余りを出す
}

//コンソール
10
3
1

このような演算に用いる記号を「演算子」
演算子の種類はプログラミング言語によって異なる

文字列の連結

package main
func main(){
  println("Hi" + "Go")
  println("1" + "2")
}

//コンソール
Hi,Go
12

文字列に対して「+」を使用すると1つの文字列にする

変数とは

データ(値)をいれておく箱
箱(変数)には名前(変数名)がついていて名前を用いて変数から値を取り出せる

変数とデータ型

var number int 
//number(変数名)、int(データ型)
var number string 
//number(変数名)、string(データ型)

変数を利用するには、まず変数を定義
「var 変数名 データ型」

コンピュータに変数を作ることを指示

データ型

"Hello, Go" //文字列(string型)
3 //整数(int型)

文字列や数値は「データ型」と呼ばれる

変数を使う

package main
func main(){
  var n int //変数nの定義
  n = 100 //変数nに100を入れる(代入する)命令
  println(n) //nを使用し100を出力
}

//コンソール
100

「=」は、変数という箱に値を入れるための記号

定義と代入

package main
func main(){
  var n int = 100
  println(n) 
}

//コンソール
100

「var n int = 100」と書けば、変数の定義と代入を同時に行える

package main

func main() {
    var message string = "Hello, 世界" //変数messageを定義して代入
    println(message)
}

変数の値の更新

package main
func main(){
  var n int = 100
  println(n)
  n = 200
  println(n)
}

//コンソール
100
200

変数は何度でも上書きできる

データ型の省略

package main
func main(){
  var n = 100
  println(n)
}

//コンソール
100

「var n int = 100」のように、変数定義と値の代入を同時に行う場合
データ型の指定を省略できる

Goがint型であることを代入される値から判断しているから

変数定義の省略

package main
func main(){
  n := 100
  println(n)
}

//コンソール
100

「var n int = 100」と同じ意味
「:=」であることに注意

printlnの便利な書き方

package main
func main(){
  a := 100
  b := 200
  println(a,b)
}

//コンソール
100 200

printlnの()内に変数aとbをコンマで区切って並べて書けば
2つの値を同時に出力できる

コンマは出力されず、スペースで区切られて1行で表示

Go言語-基本❷はこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Goの基本❶

Goの基本

プログラミング基本からGoの理解を文字におこして行こうと思います!

文字列とは

package main
func main(){
  println("Hello, Go")
}

""(ダブルクォーテーション)で囲んでいないとエラーが発生する

出力の命令

package main
func main(){
  println("Hello, Go")
}

//コンソール
Hello, Go

printlnというのは、Goが用意している「命令」の1つ

「コンソールにprintln()の中のものを出力せよ」という命令
→コンピュータが文字列をコンソールに出力

プログラムの構成

package main
func main(){
  println("Hello, Go")
}

Goのコードのファイルは、パッケージ定義部や関数定義部によって構成

ここでは「package main」と書かれたファイルの、main関数の{ }の中に命令を書くと
それが順に実行される

数値を使う

package main
func main(){
  println(1)
  println(1 + 1)
  println(1 - 2)
  println("1 - 2")
}

//コンソール
1
2
-1
1 - 2

数値は文字列と違いダブルクォーテーションで囲まない

演算を行う

package main
func main(){
  println(2 * 5) //掛け算
  println(6 / 2) //割り算
  println(9 % 2) //余りを出す
}

//コンソール
10
3
1

このような演算に用いる記号を「演算子」
演算子の種類はプログラミング言語によって異なる

文字列の連結

package main
func main(){
  println("Hi" + "Go")
  println("1" + "2")
}

//コンソール
Hi,Go
12

文字列に対して「+」を使用すると1つの文字列にする

変数とは

データ(値)をいれておく箱
箱(変数)には名前(変数名)がついていて名前を用いて変数から値を取り出せる

変数とデータ型

var number int 
//number(変数名)、int(データ型)
var number string 
//number(変数名)、string(データ型)

変数を利用するには、まず変数を定義
「var 変数名 データ型」

コンピュータに変数を作ることを指示

データ型

"Hello, Go" //文字列(string型)
3 //整数(int型)

文字列や数値は「データ型」と呼ばれる

変数を使う

package main
func main(){
  var n int //変数nの定義
  n = 100 //変数nに100を入れる(代入する)命令
  println(n) //nを使用し100を出力
}

//コンソール
100

「=」は、変数という箱に値を入れるための記号

定義と代入

package main
func main(){
  var n int = 100
  println(n) 
}

//コンソール
100

「var n int = 100」と書けば、変数の定義と代入を同時に行える

package main

func main() {
    var message string = "Hello, 世界" //変数messageを定義して代入
    println(message)
}

変数の値の更新

package main
func main(){
  var n int = 100
  println(n)
  n = 200
  println(n)
}

//コンソール
100
200

変数は何度でも上書きできる

データ型の省略

package main
func main(){
  var n = 100
  println(n)
}

//コンソール
100

「var n int = 100」のように、変数定義と値の代入を同時に行う場合
データ型の指定を省略できる

Goがint型であることを代入される値から判断しているから

変数定義の省略

package main
func main(){
  n := 100
  println(n)
}

//コンソール
100

「var n int = 100」と同じ意味
「:=」であることに注意

printlnの便利な書き方

package main
func main(){
  a := 100
  b := 200
  println(a,b)
}

//コンソール
100 200

printlnの()内に変数aとbをコンマで区切って並べて書けば
2つの値を同時に出力できる

コンマは出力されず、スペースで区切られて1行で表示

Goの基本❷はこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む