20211124のGoに関する記事は4件です。

【Golang】ポインタ型の int 変数に値をセットする

ここ 1 年で作成・更新された記事を「"golang" ポインタに値をセットする int」でググっても、わかりやすいタイトルがヒットしなかったので、自分のググラビリティとして。 TL; DR (今北産業) 変数の前に*を付ける func resetToTen(i *int) { *i = 10 // <- ここ } 動くサンプル package main import "fmt" func main() { i := 100 resetToTen(&i) fmt.Println(i) } func resetToTen(i *int) { *i = 10 } // Output: 10 オンラインで動作をみる @ Go Playground 参考文献 Go で関数に渡したポインタの値を変更するには @ Qiita 「& や * をどうつけたらいいか、よくわからなくなってしまいがち」な人は必読。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

zinのLogin

はじめに GolangのZinを使いログイン処理を書きました  Login [hoge] % tree ~/go/src/login . ├── SessionInfo │ └── sessioninfo.go ├── controller │ └── Login.go ├── crypto │ └── crypto.go ├── db │ └── db.go ├── go.mod ├── go.sum ├── login ├── main.go ├── migrate │ └── migrate.go ├── model │ ├── Login.go │ └── User.go └── template ├── login.html ├── logout.html ├── menu.html └── singup.html 7 directories, 15 files main package main import ( "log" sessioninfo "login/SessionInfo" "login/controller" "net/http" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" ) var LoginInfo sessioninfo.SessionInfo func main() { engine := gin.Default() engine.LoadHTMLGlob("template/*") store := cookie.NewStore([]byte("select")) engine.Use(sessions.Sessions("mysession", store)) engine.GET("/login", func(c *gin.Context) { c.HTML(200, "login.html", gin.H{ "UserId": "", }) }) engine.POST("/login", controller.NewLogin().LoginK) engine.GET("/singup", func(c *gin.Context) { c.HTML(200, "singup.html", gin.H{}) }) engine.POST("/singup", controller.NewLogin().SingUp) menu := engine.Group("/menu") menu.Use(sessionCheck()) { menu.GET("/top", controller.GetMenu) } engine.POST("/logout", controller.PostLogout) engine.Run(":8080") } func sessionCheck() gin.HandlerFunc { return func(c *gin.Context) { session := sessions.Default(c) LoginInfo.Name = session.Get("name") // セッションがない場合、ログインフォームをだす if LoginInfo.Name == nil { log.Println(session) log.Println("ログインしていません") c.Redirect(http.StatusMovedPermanently, "/login") c.Abort() // これがないと続けて処理されてしまう } else { c.Set("name", LoginInfo.Name) // ユーザidをセット c.Next() } log.Println("ログインチェック終わり") } } db package db import ( "fmt" "os" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" "github.com/joho/godotenv" ) func Connection() *gorm.DB { err := godotenv.Load(fmt.Sprintf("./%s.env", os.Getenv("GO_ENV"))) if err != nil { // .env読めなかった場合の処理 } DBMS := os.Getenv("login_DBMS") USER := os.Getenv("login_USER") PASS := os.Getenv("login_PASS") DBNAME := os.Getenv("login_DBNAME") CONNECT := USER + ":" + PASS + "@/" + DBNAME + "?parseTime=true" db, err := gorm.Open(DBMS, CONNECT) if err != nil { panic(err.Error()) } db.LogMode(true) return db } migrate package main import ( "login/db" "login/model" ) func main() { db := db.Connection() defer db.Close() db.AutoMigrate(&model.Login{}) db.AutoMigrate(&model.User{}) } model DB package model import ( _ "github.com/go-sql-driver/mysql" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type Login struct { gorm.Model Name string `gorm:"unique; not null"` Pass string `gorm:"not null"` } crypto package crypto import ( "golang.org/x/crypto/bcrypt" ) // PasswordEncrypt パスワードをhash化 func PasswordEncrypt(password string) (string, error) { hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) return string(hash), err } // CompareHashAndPassword hashと非hashパスワード比較 func CompareHashAndPassword(hash, password string) error { return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) } Sessions package sessioninfo type SessionInfo struct { Name interface{} } Controller package controller import ( "log" "login/crypto" "login/db" "login/model" "net/http" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) type Login struct{} func NewLogin() *Login { return &Login{} } func LoginM(c *gin.Context, name string) { session := sessions.Default(c) session.Set("name", name) session.Save() } func getUser(username string) model.Login { db := db.Connection() var user model.Login db.First(&user, "name = ?", username) db.Close() return user } func (l *Login) LoginK(c *gin.Context) { db := db.Connection() defer db.Close() log.Println("ログイン処理") name := c.PostForm("name") LoginM(c, name) // // 同じパッケージ内のログイン処理 dbPassword := getUser(c.PostForm("name")).Pass log.Println(dbPassword) // フォームから取得したユーザーパスワード formPassword := c.PostForm("pass") // ユーザーパスワードの比較 if err := crypto.CompareHashAndPassword(dbPassword, formPassword); err != nil { log.Println("ログインできませんでした") c.Abort() } else { log.Println("ログインできました") c.Redirect(http.StatusMovedPermanently, "/menu/top") } } func (l *Login) SingUp(c *gin.Context) { var form Login if err := c.Bind(&form); err != nil { c.Abort() } else { username := c.PostForm("name") password := c.PostForm("pass") // 登録ユーザーが重複していた場合にはじく処理PasswordEncrypt passwordEncrypt, _ := crypto.PasswordEncrypt(password) db := db.Connection() defer db.Close() if err := db.Create(&model.Login{Name: username, Pass: passwordEncrypt}).GetErrors(); err != nil { } c.Redirect(302, "/login") } } func PostLogout(c *gin.Context) { log.Println("ログアウト処理") Logout(c) // 同じパッケージ内のログアウト処理 // ログインフォームに戻す c.HTML(http.StatusOK, "login.html", gin.H{ "name": "", "ErrorMessage": "", }) } func Logout(c *gin.Context) { session := sessions.Default(c) log.Println("セッション取得") session.Clear() log.Println("クリア処理") session.Save() } func GetMenu(c *gin.Context) { name, _ := c.Get("name") // ログインユーザの取得 c.HTML(http.StatusOK, "menu", gin.H{"name": name}) }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go 文法 2

Go文法 前回の続き フロー制御 if package main import( "fmt" ) func main(){ s := "baz" if s == "bus" { fmt.Println("Hello") } else if s=="baz" { //else if fmt.Println("world") }else{ //else fmt.Println("Hello world!") } if n := 100; n % 2 == 0{// nに100を代入; nの余りが0ならばの判別式 fmt.Println("偶数") }else{ fmt.Println("奇数") } } [hoge] % go build if.go ~/go/src [hoge] % ./if ~/go/src world 偶数 ifの判別の前に値をすることも可能 for package main import "fmt" func main(){ for i := 0; i < 5; i++ { fmt.Println(i) } } [hoge] % go build for.go ~/go/src [hoge] % ./for ~/go/src 0 1 2 3 4 package main import( "fmt" ) func main() { sum:=1 for sum < 1000 { //省略系 (whileみたいな感覚) sum += sum } fmt.Println(sum) } [hoge] % go build for3.go ~/go/src [hoge] % ./for3 ~/go/src 1024 ``` Swicth package main import( "fmt" ) func main(){ lang := "Go" switch lang{ case "Ruby": fmt.Println("This is Ruby") case "Go": fmt.Println("This is Go") default: fmt.Println("This is a programming language") } } [hoge] % go build switch.go ~/go/src [hoge] % ./switch ~/go/src This is Go package main import( "fmt" ) func main(){ lang := "Ruby" switch{ case lang == "Ruby": fmt.Println("This is Ruby") case lang == "Go": fmt.Println("This is Go") default: fmt.Println("This is a programming ") } } [hoge] % go build switch2.go ~/go/src [hoge] % ./switch2 ~/go/src This is Ruby Switchには2パターンの書き方が存在する。 Defer(遅延) Deferへ渡した関数の実行を呼び出した元の関数の終わりまで処理を遅延させるプログラミング package main import ( "fmt" ) func main(){ //元の関数 defer fmt.Println("World") //渡した関数 fmt.Println fmt.Println("Hello") //=> Hello //=> World } [Gami] % go build defer.go ~/go/src [Gami] % ./defer ~/go/src Hello World package main import( "fmt" ) func main(){ defer fmt.Println("Golang") //defer1 defer fmt.Println("Ruby") //defer2 fmt.Println("JS") } [hoge] % go build defer2.go ~/go/src [hoge] % ./defer2 ~/go/src JS Ruby Golang ベンチマーク package main import ( "math/rand" // 乱数を使う上でインポート "testing" //testする上で必要 "time" //乱数 ) func VerificationIfElse(randomNum int) string { if randomNum <= 10 { return "10より小さい" } else if randomNum >= 11 && randomNum <= 20 { return "10より大きく20より小さい" } else if randomNum >= 21 && randomNum <= 30 { return "20より大きく30より小さい" } else if randomNum >= 31 && randomNum <= 40 { return "30より大きく40より小さい" } else if randomNum >= 41 && randomNum <= 50 { return "40より大きく50より小さい" } return "" } func VerificationSwitch(randomNum int) string { switch { case randomNum <= 10: return "10より小さい" case randomNum >= 11 && randomNum <= 20: return "10より大きく20より小さい" case randomNum >= 21 && randomNum <= 30: return "20より大きく30より小さい" case randomNum >= 31 && randomNum <= 40: return "30より大きく40より小さい" case randomNum >= 41 && randomNum <= 50: return "40より大きく50より小さい" } return "" } func BenchmarkVerificationIfElse(b *testing.B) { for i := 0; i < b.N; i++ { rand.Seed(time.Now().UnixNano()) //乱数の元になるシードを与える randomNum := rand.Intn(50) VerificationIfElse(randomNum) } } func BenchmarkVerificationSwitch(b *testing.B) { for i := 0; i < b.N; i++ { rand.Seed(time.Now().UnixNano()) randomNum := rand.Intn(50) VerificationSwitch(randomNum) } } [hoge] % go test -bench=. -benchmem ~/go/src/test goos: darwin goarch: amd64 pkg: example.com/go/src/test cpu: Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz BenchmarkVerificationIfElse-8 144904 8149 ns/op 0 B/op 0 allocs/op BenchmarkVerificationSwitch-8 145306 8135 ns/op 0 B/op 0 allocs/op PASS ok example.com/go/src/test 2.669s [hoge] % go test -bench=. -benchmem ~/go/src/test goos: darwin goarch: amd64 pkg: example.com/go/src/test cpu: Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz BenchmarkVerificationIfElse-8 145984 8355 ns/op 0 B/op 0 allocs/op BenchmarkVerificationSwitch-8 143708 8329 ns/op 0 B/op 0 allocs/op PASS ok example.com/go/src/test 2.684s Ifとswitchは処理速度的には変わらないことがわかった。 実行した回数 1回あたりの実行に掛かった時間(ns/op) 1回あたりのアロケーションで確保した容量(B/op) 1回あたりのアロケーション回数(allocs/op) 参考資料 https://golang.org/pkg/testing/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golang (文法) 1

Go基礎 Golangの文法をメモ書き程度に載せておきます 型宣言 package main import "fmt" func main(){ var msg string msg = "Hello world" msg2 := "Hello world2" // var省略 var a , b int a , b = 10 , 15 c , d := 13 , 14 var( e bool f float64 ) fmt.Printf("a: %d b: %d c: %d d: %d e: %t f: %f msg: %s msg2: %s" , a , b ,c , d , e , f , msg , msg2 ) } go build aa.go ~/go/src [hoge] % ./aa ~/go/src a: 10 b: 15 c: 13 d: 14 e: false f: 0.000000 msg: Hello world msg2: Hello world2% 定数 package main import "fmt" const Num = 2 func main(){ const str = "Hello World" fmt.Println(str) fmt.Println(Num) } [hoge] % go build cons.go [hoge] % ./cons Hello World 2 四則演算式 package main import "fmt" func main(){ a := 10 b := 3 fmt.Println( a + b ) fmt.Println( a - b ) fmt.Println( a * b ) fmt.Println( a / b ) fmt.Println( a % b ) } [hoge] % go build sanjutu.go ~/go/src [hoge] % ./sanjutu ~/go/src 13 7 30 3 1 論理式 package main import ( "fmt" ) func main() { fmt.Println(true && true) fmt.Println(true && false) fmt.Println(true || false) fmt.Println(false || false) fmt.Println(!true) fmt.Println(!false) } [hoge] % go build ronri.go ~/go/src [hoge] % ./ronri ~/go/src true false true false false true 関数 package main import "fmt" func main(){ fmt.Println(addOne(1)) } func addOne(i int) int { return i + 10 } [hoge] % go build func.go ~/go/src [hoge] % ./func ~/go/src 11
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む