0
0

はじめに

42Tokyoに入ってGo言語を触りだして少し経ちますが、Go言語の仕様そのものについて気になる部分がありました。
Go言語にはパッケージに定義されている関数とは異なり、builtinと呼ばれる組み込み関数群があります。例を挙げると、len()やappend()、panic()などがこれにあたります。
さて、Go言語には型変換と呼ばれる仕組みがあります。

var i int = 42
var f float64 = float64(i)

このコードは、int型の42をfloat64に変換しています。このfloat64は一体何の関数かが気になり、今回これを調べることにしました。

builtin.goを読む

Go言語の組み込み関数は、builtinパッケージのbuiltin.goに記載されています。
コードそのものが書かれているわけではなく、ここには事前に宣言された定数や変数、型などが記載されています。
builtin.goでfloat64について直接的に記述されている部分はここだけです。

// float64 is the set of all IEEE 754 64-bit floating-point numbers.
type float64 float64

intをfloat64に変える関数の記載はありませんでした。

The Go Programming Language Specificationを読む

The Go Programming Language SpecificationとはGoの言語仕様書で、ここに型変換についての記述した項目Conversionsがあります。

A conversion changes the type of an expression to the type specified by the conversion. A conversion may appear literally in the source, or it may be implied by the context in which an expression appears.

An explicit conversion is an expression of the form T(x) where T is a type and x is an expression that can be converted to type T.

Conversion = Type "(" Expression [ "," ] ")" .

この項目について読むと、型変換はConversion = T(x)(T: 型のtype, x: Tに変換可能な式x)によって行われることがわかります。
ちなみに、変換可能なTとxの関係性は次のように書かれています。

A non-constant value x can be converted to type T in any of these cases:

  • x is assignable to T.
  • ignoring struct tags (see below), x's type and T are not type parameters but have identical underlying types.
  • ignoring struct tags (see below), x's type and T are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.
  • x's type and T are both integer or floating point types.
  • x's type and T are both complex types.
  • x is an integer or a slice of bytes or runes and T is a string type.
  • x is a string and T is a slice of bytes or runes.
  • x is a slice, T is an array [Go 1.20] or a pointer to an array [Go 1.17], and the slice and array types have identical element types.

conversions.goを読む

先程のconversionの実体はここに記述されています。funcと関数定義されていることからわかるように、conversionはtypes2パッケージに入っている関数です。

func (check *Checker) conversion(x *operand, T Type)

Go言語のコンパイラや静的解析ツールで用いられる型チェッカー関数がtypes2パッケージに含まれていて、基本的にconversion関数をユーザーが記述することはありません。
このような記述を行った場合、goのコンパイラが読み取ってconversion()を適用するようです。

var i int = 42
var f float64 = float64(i)

結論

float64()はbuiltin関数ではない。float64()という関数が存在するわけではなく、float64()と記述することでconversion関数がコンパイル時に呼び出されるようになる。

さいごに

Go初心者なので、多分理解が不十分な箇所があると思います。
もし見つけたら、教えていただけると嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0