空インターフェイスと型アサーション

空インターフェイスとは、定義すべきメソッドを持たないインターフェイスのことだ。言い換えるとどんな型にも当てはまる。空インターフェイスの配列やスライスはどんな型でも格納することができる。下の例ではスライス a に整数、実数、文字列を格納している。
Go は静的型付け言語なので、スライスに格納されているのが何の型なのかわからないのでは都合が悪い。そこで、型をチェックする機能がある。それが型アサーションだ。型アサーションは「変数.(型)」という書き方をして、変数が型と一致すればその値と true の2つの値が返ってくる。一致しなければゼロ値と false だ。下の例では、この型アサーションを使って、スライスに含まれる整数と実数のそれぞれの合計を求めている。

package main

import "fmt"

func sumOfInt(ary []interface{}) int {
    sum := 0
    for _, x := range ary {
        v, ok := x.(int)
        if ok {
            sum += v
        }
    }
    return sum
}

func sumOfFloat(ary []interface{}) float64 {
    sum := 0.0
    for _, x := range ary {
        v, ok := x.(float64)
        if ok {
            sum += v
        }
    }
    return sum
}

func main() {
    a := []interface{}{ 1, 1.1, "abc", 2, 2.2, "def", 3, 3.3 }
    fmt.Println(sumOfInt(a))
    fmt.Println(sumOfFloat(a))
}
^o^ > go run interface3.go
6
6.6

Perlの配列をn個ずつの配列に分割する

splice して push する。破壊的なので注意。

use strict;
use warnings;

sub chunk {
    my $ary = shift @_;
    my $n = shift @_;
    my $result = [];

    while (@$ary) {
        my @s = splice(@$ary, 0, $n);
        push(@$result, \@s);
    }

    return $result;
}

my $array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

print("array:", @$array, "\n");

my $chunked = chunk($array, 3);
foreach my $c (@$chunked) {
    print("chunk:", @$c);
    print("\n");
}

print("array:", @$array, "\n");
^o^ > perl chunk.pl
array:0123456789
chunk:012
chunk:345
chunk:678
chunk:9
array: