Upgrade to Pro — share decks privately, control downloads, hide ads and more …

入門Go言語仕様輪読会 Assignability / Go Language Specification Assignability

yyh_gl
March 18, 2021

入門Go言語仕様輪読会 Assignability / Go Language Specification Assignability

入門Go言語仕様輪読会 #2 で発表した内容です。
https://gospecreading.connpass.com/event/205420/

go-talks上で見てもらうとスライド内のコードを実行できます!
https://go-talks.appspot.com/github.com/yyh-gl/slide-decks/210318_gospecreading_assignability.slide

yyh_gl

March 18, 2021
Tweet

More Decks by yyh_gl

Other Decks in Technology

Transcript

  1. Assignability
    Assignability
    Go
    Go
    18 March 2021
    18 March 2021
    yyh-gl
    yyh-gl

    View Slide

  2. 2
    2

    View Slide

  3. yyh-gl Honda, Yusuke
    yyh-gl Honda, Yusuke
    DMM.com Go
    DMM.com Go
    Go
    Go
    The Go Programming Language Specification
    The Go Programming Language Specification
    (https://yyh-gl.github.io/tech-blog/blog/uncredible-codes-from-go-spec/)
    (https://yyh-gl.github.io/tech-blog/blog/uncredible-codes-from-go-spec/)
    Twitter: @yyh_gl
    Twitter: @yyh_gl (https://twitter.com/yyh_gl)
    (https://twitter.com/yyh_gl) 3
    3

    View Slide

  4. Go Assignability
    Go Assignability
    1. Assignability
    1. Assignability
    2. Assignable
    2. Assignable
    3.
    3.
    Go Assignability
    Go Assignability (https://golang.org/ref/spec#Assignability)
    (https://golang.org/ref/spec#Assignability) 4
    4

    View Slide

  5. Assignability
    Assignability
    5
    5

    View Slide

  6. Assignability =
    Assignability =
    Go 6
    Go 6 6
    6

    View Slide

  7. Assignable
    Assignable
    7
    7

    View Slide

  8. Assignable
    Assignable
    x 6
    x 6
    x T Assignable
    x T Assignable
    8
    8

    View Slide

  9. 1
    1
    x T identical
    x T identical
    identical syumai
    identical syumai (hoge)
    (hoge)
    package main
    package main
    import "fmt"
    import "fmt"
    func main() {
    func main() {
    var x int = 1
    var x int = 1
    var t1 int = x // t1およびxの型はint
    var t1 int = x // t1およびxの型はint
    fmt.Println(t1) // 1
    fmt.Println(t1) // 1
    var y string = "yyy"
    var y string = "yyy"
    var t2 int = y // t2とyの型が異なるのでエラー
    var t2 int = y // t2とyの型が異なるのでエラー
    }
    } Run
    9
    9

    View Slide

  10. 2
    2
    T x V underlying type
    T x V underlying type
    && T V defined type
    && T V defined type
    package main
    package main
    import "fmt"
    import "fmt"
    const one int = 1
    const one int = 1
    type (
    type (
    T1 struct{ number int } // T1のunderlying typeはstruct{ number int }
    T1 struct{ number int } // T1のunderlying typeはstruct{ number int }
    T2 int // T2のunderlying typeはint
    T2 int // T2のunderlying typeはint
    )
    )
    func main() {
    func main() {
    // underlying typeが同じ(struct{ number int })であり、
    // underlying typeが同じ(struct{ number int })であり、
    // なおかつ、一方(struct{ number int }{number: 1})がdefined typeではないため代入可能である
    // なおかつ、一方(struct{ number int }{number: 1})がdefined typeではないため代入可能である
    var t1 T1 = struct{ number int }{number: 1}
    var t1 T1 = struct{ number int }{number: 1}
    fmt.Println(t1) // {1}
    fmt.Println(t1) // {1}
    // underlying typeは同じ(int)だが、T2およびintがともにdefined typeであるため代入不可能である
    // underlying typeは同じ(int)だが、T2およびintがともにdefined typeであるため代入不可能である
    var t2 T2 = one
    var t2 T2 = one
    }
    } Run
    10
    10

    View Slide

  11. 2
    2
    underlying type defined type
    underlying type defined type
    DQNEO Nobishii
    DQNEO Nobishii
    underlying type by. DQNEO
    underlying type by. DQNEO (https://docs.google.com/presentation/d/1JUiZ-SdXbFvi8_hJZ-ouJbDdEJGT-
    (https://docs.google.com/presentation/d/1JUiZ-SdXbFvi8_hJZ-ouJbDdEJGT-
    op827O7V7HUAWU/edit#slide=id.p)
    op827O7V7HUAWU/edit#slide=id.p)
    defined type by. Nobishii
    defined type by. Nobishii
    (https://docs.google.com/presentation/d/1JSsrv404ZDJSnxp4UcJ3iVYDJAiT3RyETMe9AvbkxuY/edit#slide=id.gbb52947b14_0_62)
    (https://docs.google.com/presentation/d/1JSsrv404ZDJSnxp4UcJ3iVYDJAiT3RyETMe9AvbkxuY/edit#slide=id.gbb52947b14_0_62) 11
    11

    View Slide

  12. 3
    3
    T x T
    T x T
    package main
    package main
    import "fmt"
    import "fmt"
    type (
    type (
    T1 interface{}
    T1 interface{}
    T2 interface {
    T2 interface {
    String() string
    String() string
    }
    }
    )
    )
    func main() {
    func main() {
    x := 1
    x := 1
    var t1 T1 = x // xはインターフェースT1を満たしている
    var t1 T1 = x // xはインターフェースT1を満たしている
    fmt.Println(t1) // 1
    fmt.Println(t1) // 1
    var t2 T2 = x // xはインターフェースT2を満たしていないので代入不可能である
    var t2 T2 = x // xはインターフェースT2を満たしていないので代入不可能である
    }
    } Run
    12
    12

    View Slide

  13. 4
    4
    x T channel type
    x T channel type
    && T x V
    && T x V
    && T V defined type
    && T V defined type
    package main
    package main
    import "fmt"
    import "fmt"
    type T <-chan int // Tはchannel type
    type T <-chan int // Tはchannel type
    func main() {
    func main() {
    x1 := make(chan int, 1) // x1は要素の型がintの双方向チャネル
    x1 := make(chan int, 1) // x1は要素の型がintの双方向チャネル
    var t1 T = x1 // t1およびx1の要素の型は同じ(int)
    var t1 T = x1 // t1およびx1の要素の型は同じ(int)
    fmt.Println(t1) // アドレス情報
    fmt.Println(t1) // アドレス情報
    x2 := make(chan string, 1) // x2は要素の型がstringの双方向チャネル
    x2 := make(chan string, 1) // x2は要素の型がstringの双方向チャネル
    var t2 T = x2 // t2およびx2の要素の型が異なるので代入不可能である
    var t2 T = x2 // t2およびx2の要素の型が異なるので代入不可能である
    }
    } Run
    13
    13

    View Slide

  14. 5
    5
    x nil
    x nil
    T , , , ,
    T , , , ,
    package main
    package main
    type (
    type (
    Tp *int
    Tp *int
    Tf func()
    Tf func()
    Ts []int
    Ts []int
    Tm map[int]int
    Tm map[int]int
    Tc chan int
    Tc chan int
    Ti interface{}
    Ti interface{}
    )
    )
    func main() {
    func main() {
    var _ Tp = nil // Tpはポインタ && 値(x)はnil
    var _ Tp = nil // Tpはポインタ && 値(x)はnil
    var _ Tf = nil // Tfは関数 && 値(x)はnil
    var _ Tf = nil // Tfは関数 && 値(x)はnil
    var _ Ts = nil // Tsはスライス && 値(x)はnil
    var _ Ts = nil // Tsはスライス && 値(x)はnil
    var _ Tm = nil // Tmはマップ && 値(x)はnil
    var _ Tm = nil // Tmはマップ && 値(x)はnil
    var _ Tc = nil // Tcはチャネル && 値(x)はnil
    var _ Tc = nil // Tcはチャネル && 値(x)はnil
    var _ Ti = nil // Tiはインターフェース && 値(x)はnil
    var _ Ti = nil // Tiはインターフェース && 値(x)はnil
    }
    } Run
    14
    14

    View Slide

  15. 5
    5
    x nil
    x nil
    package main
    package main
    import "fmt"
    import "fmt"
    type T *int
    type T *int
    func main() {
    func main() {
    var x func() // 関数型のゼロ値はnil
    var x func() // 関数型のゼロ値はnil
    fmt.Println(x) //
    fmt.Println(x) //
    var t T = x // xはnilだが事前宣言された識別子としてのnilではないため代入不可能である
    var t T = x // xはnilだが事前宣言された識別子としてのnilではないため代入不可能である
    }
    } Run
    15
    15

    View Slide

  16. 6
    6
    x T untyped constant
    x T untyped constant
    16
    16

    View Slide

  17. num
    num
    → Constants
    → Constants
    Go Constants
    Go Constants (https://golang.org/ref/spec#Constants)
    (https://golang.org/ref/spec#Constants)
    package main
    package main
    import "fmt"
    import "fmt"
    const num = 1 // 型が宣言されていない=型無し定数
    const num = 1 // 型が宣言されていない=型無し定数
    func main() {
    func main() {
    var i int = num // 暗黙的な変換により定数numはint型として扱われる
    var i int = num // 暗黙的な変換により定数numはint型として扱われる
    fmt.Printf("%T", i) // int
    fmt.Printf("%T", i) // int
    }
    } Run
    17
    17

    View Slide

  18. 6
    6
    x T untyped constant
    x T untyped constant
    package main
    package main
    import "fmt"
    import "fmt"
    // 型が宣言されていない=型無し定数
    // 型が宣言されていない=型無し定数
    const x = 1000
    const x = 1000
    func main() {
    func main() {
    var t1 int = x // x=1000はintで表現可能である
    var t1 int = x // x=1000はintで表現可能である
    fmt.Println(t1) // 1000
    fmt.Println(t1) // 1000
    var t2 int8 = x // x=1000はint8(-128~127)で表現できないため代入不可能である
    var t2 int8 = x // x=1000はint8(-128~127)で表現できないため代入不可能である
    }
    } Run
    18
    18

    View Slide

  19. 19
    19

    View Slide

  20. Assignable
    Assignable
    1. 値xの型が型Tとidenticalである
    1. 値xの型が型Tとidenticalである
    2. 型Tと値xの型Vが同じunderlying typeを持つ
    2. 型Tと値xの型Vが同じunderlying typeを持つ
    && 型Tまたは型Vのいずれかがdefined typeでない
    && 型Tまたは型Vのいずれかがdefined typeでない
    3. 型Tはインターフェースであり、値xがインターフェースTを満たしている
    3. 型Tはインターフェースであり、値xがインターフェースTを満たしている
    4. 値xは双方向チャネルであり、型Tはchannel typeである
    4. 値xは双方向チャネルであり、型Tはchannel typeである
    && 型Tおよび値xの型Vが持つ要素の型が同じである
    && 型Tおよび値xの型Vが持つ要素の型が同じである
    && 型Tまたは型Vのいずれかがdefined typeでない
    && 型Tまたは型Vのいずれかがdefined typeでない
    5. 値xは事前宣言された識別子としてのnilであり、
    5. 値xは事前宣言された識別子としてのnilであり、
    型Tはポインタまたは関数, スライス, マップ, チャネル, インターフェースのどれかである
    型Tはポインタまたは関数, スライス, マップ, チャネル, インターフェースのどれかである
    6. 値xは型Tの値によって表現可能な型無し定数(untyped constant)である
    6. 値xは型Tの値によって表現可能な型無し定数(untyped constant)である
    20
    20

    View Slide

  21. Nobishii DQNEO
    Nobishii DQNEO
    21
    21

    View Slide

  22. Thank you
    Thank you
    yyh-gl
    yyh-gl
    @yyh_gl
    @yyh_gl (http://twitter.com/yyh_gl)
    (http://twitter.com/yyh_gl)

    View Slide