Skip to content

Instantly share code, notes, and snippets.

@tenntenn
Last active September 28, 2018 08:56
Show Gist options
  • Save tenntenn/3049e06b301b1d7df952d41b12bef7d8 to your computer and use it in GitHub Desktop.
Save tenntenn/3049e06b301b1d7df952d41b12bef7d8 to your computer and use it in GitHub Desktop.
contract tricks

Contract Tricks

こういうことができたらいいなと言う発想から考えています。

contract ptr(t T) {
    *t
}

type Ptr struct {
    v reflect.Value
}

func PointerOf(type P ptr) (v P) Ptr {
    return Ptr{v: reflect.ValueOf(v)}
}

func (p Ptr) Elem() reflect.Value {
    return p.v.Elem()
}

メソッド

以下の定義には、フィールドが関数の場合を含む。

contract Stringer(t T) {
    // フィールドかメソッドか分からない
    t.String()
}
contract Stringer(t T) {
    var _ interface{
        String() string
    } = t
}

フィールド

以下の定義には、メソッドも含む。

contract Field(t T) {
   // メソッドも含むからダメ
    t.Foo
}

メソッドは代入できないので、代入する。

contract Field(t T) {
    t.Foo = t.Foo
}

インタフェース

型アサーションができるのはインタフェースのみに限定される。

contract Interface (_ T) {
    T.(struct{})
}

配列

lenにポインタを渡せるのは、配列のみ。

contract Array(_ T) {
    len(&T{})
}

スライス

appendが呼べるのはスライスのみ。

contract Slice(t T) {
    append(t, t...)
}

マップ

deleteに渡せるのはマップのみ、型が分からないのでfor rangeを使う。

contract Map(t T) {
    for k, _ := range t {
        delete(t, k)
    }
}

受信可能なチャネル

受信してみる。型は分からないので受け取らない。

contract Receivable(t T) {
    <-t
}

送信可能なチャネル

closeできるのは送信可能なチャネル。 受信のみのチャネルはcloseに渡すとコンパイルエラー。

contract Sendable(t T) {
    close(t)
}

ポインタ

アドレス演算の*が使えるのはポインタのみ。

contract Pointer(t T) {
    *t
}

名前付き型

contract NamedType(_ T) {
    var _ struct {
        T
    }
}

T1とT2が別の型

contract NeqT1T2(_ T1, _ T2) {
    var _ struct {
        T1
        T2
    }
}

組み込み型以外の名前付き型

contract NotBuiltin(_ T) {
    var _ struct {
        int;int8;int16;int32;int64
        uint;uint8;uint16;uint32;uint64
        uintptr;byte;rune
        float32;float64
        complex64;complex128
        string
        bool
        error
        T
    }
}

どの型にもマッチしないもの

その場で作った型は他から参照できない。

contract Deprecated(t T) {
   type D struct{}
   var _ D = t
}

定義が難しいもの

関数

  • 呼び出すには引数が必要

構造体

  • 組み込み関数で構造体だけを対象にしたものがない
  • T{}みたいな初期化は配列やスライスなどでも可能
  • ==は配列でも使える
    • フィールドが関数やスライスだと==が使えない
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment