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 full-size slide

  2. 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 full-size slide

  3. 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 full-size slide

  4. Assignability
    Assignability
    5
    5

    View full-size slide

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

    View full-size slide

  6. Assignable
    Assignable
    7
    7

    View full-size slide

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

    View full-size slide

  8. 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 full-size slide

  9. 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 full-size slide

  10. 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 full-size slide

  11. 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 full-size slide

  12. 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 full-size slide

  13. 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 full-size slide

  14. 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 full-size slide

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

    View full-size slide

  16. 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 full-size slide

  17. 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 full-size slide

  18. 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 full-size slide

  19. Nobishii DQNEO
    Nobishii DQNEO
    21
    21

    View full-size slide

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

    View full-size slide