変数とデータ型
キッチンで料理をしている場面を想像してください:変数はラベル付きの保存ボックスです — ラベルが名前で、ボックスにデータが入っています;データ型はボックスの形です — 丸いボックスにはスープが、四角いボックスにはおかずが入り、混ぜることはできません。Goは「ボックス」の管理に非常に厳格です:どのボックス(型)が必要か宣言し、どの内容を入れるか(代入)を指定し、空のボックスにもデフォルトの内容(ゼロ値)があります。
1. コアコンセプト
1.1 変数宣言:var vs :=
Goには変数を宣言する2つの方法があります:
| 方法 | 構文 | ユースケース | スコープ |
|---|---|---|---|
var |
var name int |
パッケージレベル変数、明示的な型が必要 | 関数内外 |
短縮宣言 := |
name := 10 |
ローカル変数、型推論 | 関数内のみ |
主な違い:
varは代入なしで宣言可能(ゼロ値が自動使用);:=は代入が必要。varは関数の外で宣言可能;:=は関数内でのみ使用可能。:=は宣言+代入の省略形;左辺の少なくとも1つの変数は新しいものでなければならない。
1.2 基本データ型
| カテゴリ | 型 | 説明 | 例 |
|---|---|---|---|
| 整数 | int, int8, int16, int32, int64 |
符号付き整数 | var a int = 42 |
| 符号なし整数 | uint, uint8, uint16, uint32, uint64 |
非負整数 | var b uint = 100 |
| 浮動小数点 | float32, float64 |
小数(デフォルトfloat64) |
var c float64 = 3.14 |
| ブール値 | bool |
true / false |
var d bool = true |
| 文字列 | string |
不変のバイトシーケンス | var e string = "hello" |
| バイト | byte |
uint8のエイリアス、1バイトを表現 |
var f byte = 'A' |
| Unicode文字 | rune |
int32のエイリアス、1つのUnicodeコードポイントを表現 |
var g rune = '中' |
プラットフォーム依存型: intとuintは32ビットシステムでは32ビット、64ビットシステムでは64ビットです。日常開発では、ほとんどの場合intで十分です。
1.3 ゼロ値メカニズム
Goで変数が宣言されても代入されない場合、nullや未定義ではなくゼロ値に自動初期化されます:
| 型 | ゼロ値 |
|---|---|
整数(int, uintなど) |
0 |
浮動小数点(float32, float64) |
0.0 |
ブール値(bool) |
false |
文字列(string) |
""(空文字列) |
| ポインタ、スライス、map、チャネル、関数、インターフェース | nil |
これはGoの安全メカニズムです — 「値がない」変数が存在せず、多くのヌルポインターエラーを回避できます。
1.4 定数とiota
constはコンパイル時に値が確定し、その後変更できない定数を宣言します。iotaはconstブロック内で0から自動インクリメントする定数生成子で、列挙型の定義に適しています。
1.5 型変換
Goは暗黙の型変換をサポートしません。異なる型は明示的に変換する必要があります:
var i int = 42
var f float64 = float64(i) // int → float64
var u uint = uint(f) // float64 → uint
1.6 fmtパッケージのフォーマット出力
fmtはGoで最もよく使われるフォーマットパッケージです。主要な関数:
| 関数 | 用途 | 例 |
|---|---|---|
fmt.Println |
改行付きで出力 | fmt.Println("hello") |
fmt.Printf |
フォーマット出力(改行なし) | fmt.Printf("value=%d", 42) |
fmt.Sprintf |
文字列にフォーマット(出力なし) | s := fmt.Sprintf("%d", 42) |
よく使うフォーマット指定子:%d(整数)、%f(浮動小数点)、%s(文字列)、%t(ブール値)、%T(型)、%v(汎用値)、%q(引用符付き文字列)。
2. 基本構文/使い方
変数宣言
// 方法1:var宣言(関数内外で使用可能)
var name string // 宣言、ゼロ値 ""
var age int = 25 // 宣言と代入
var score = 98.5 // 型推論でfloat64
// 方法2:短縮宣言 :=(関数内のみ)
city := "Beijing" // 宣言と代入、stringと推論
count := 100 // intと推論
// 一括宣言
var (
width int = 10
height int = 20
area float64
)
varで変数を宣言して使用しない場合、Goコンパイラはdeclared and not usedエラーを報告します。これはGoの設計哲学です:デッドコードを許可しません。短縮宣言:=也同样です。
定数宣言
// 単一定数
const Pi = 3.14159
const Language string = "Go"
// 一括定数 + iota列挙
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
iotaはconstブロック内でのみ有効で、新しい行ごとに1ずつ自動インクリメントされます。_を使ってスキップしても、iotaはインクリメントされます。
型変換
var i int = 100
var f float64 = float64(i) // 明示的変換:int → float64
var s string = string(rune(i)) // int → rune → string(注意:数値を文字列にはしません)
// 数値を文字列に変換する正しい方法:
s2 := fmt.Sprintf("%d", i) // "100"
string(65)は文字"A"(ASCIIコード)を生成し、"65"ではありません。数値を10進数の文字列に変換するには、fmt.Sprintfまたはstrconv.Itoaを使用してください。
3. コード例
例1:基本的な使い方(難易度⭐)
シナリオ: 異なる型の変数を宣言し、その値と型を出力します。
package main
import "fmt"
func main() {
// ========== 変数宣言 ==========
// 1. var宣言 + 明示的な型
var name string = "Alice"
var age int = 28
// 2. var宣言 + 型推論(コンパイラが値から型を推論)
salary := 15000.5 // float64と推論
// 3. 短縮変数宣言(最も一般的)
isEmployed := true
city := "New York"
// 4. ゼロ値のデモ — 代入なしで宣言
var defaultInt int // ゼロ値:0
var defaultFloat float64 // ゼロ値:0
var defaultBool bool // ゼロ値:false
var defaultString string // ゼロ値:""
// ========== 出力 ==========
fmt.Println("=== 個人情報 ===")
fmt.Printf("名前: %s (型: %T)\n", name, name)
fmt.Printf("年齢: %d (型: %T)\n", age, age)
fmt.Printf("給与: %.1f (型: %T)\n", salary, salary)
fmt.Printf("雇用状況: %t (型: %T)\n", isEmployed, isEmployed)
fmt.Printf("都市: %s (型: %T)\n", city, city)
fmt.Println("\n=== ゼロ値デモ ===")
fmt.Printf("int ゼロ値: %d\n", defaultInt)
fmt.Printf("float64 ゼロ値: %v\n", defaultFloat)
fmt.Printf("bool ゼロ値: %t\n", defaultBool)
fmt.Printf("string ゼロ値: %q\n", defaultString) // %qは引用符付き文字列を表示
}
出力:
=== 個人情報 ===
名前: Alice (型: string)
年齢: 28 (型: int)
給与: 15000.5 (型: float64)
雇用状況: true (型: bool)
都市: New York (型: string)
=== ゼロ値デモ ===
int ゼロ値: 0
float64 ゼロ値: 0
bool ゼロ値: false
string ゼロ値: ""
要点:
%Tは変数の基本型を出力します。%qは文字列に引用符を付け、デバッグ中に空文字列と非空文字列を区別しやすくします。- ゼロ値メカニズムにより、変数は常に明確な値を持ち、Goの重要な安全保証です。
例2:中級的な使い方(難易度⭐⭐)
シナリオ: 定数、iotaを使った列挙型の定義、実践的な型変換を使用します。
package main
import "fmt"
// ========== iota列挙:ロール権限の定義 ==========
type Role int // intを基本型とするカスタム型
const (
Guest Role = iota // 0:ゲスト
Member // 1:メンバー
Admin // 2:管理者
SuperAdmin // 3:スーパー管理者
)
// RoleにString()メソッドを実装し、出力を容易にする
func (r Role) String() string {
names := [...]string{"Guest", "Member", "Admin", "Super Admin"}
if int(r) < len(names) {
return names[r]
}
return "Unknown Role"
}
// ========== iotaの高度な使い方:ビット権限フラグ ==========
type Permission int
const (
Read Permission = 1 << iota // 1 (001)
Write // 2 (010)
Execute // 4 (100)
)
// ========== 実践的な型変換 ==========
func main() {
// --- iota列挙の使用 ---
var userRole Role = Admin
fmt.Printf("ユーザーロール: %s (値: %d)\n", userRole, userRole)
// --- ビット権限の組み合わせ ---
userPerm := Read | Write // 組み合わせ権限:Read + Write = 3 (011)
fmt.Printf("\nユーザー権限値: %d (バイナリ: %03b)\n", userPerm, userPerm)
fmt.Printf("読み取り権限あり? %t\n", userPerm&Read != 0)
fmt.Printf("実行権限あり? %t\n", userPerm&Execute != 0)
// --- 型変換 ---
var temperature float64 = 36.6
var intTemp int = int(temperature) // float64 → int(切り捨て、四捨五入ではない)
fmt.Printf("\n体温: %.1f°C → 整数部分: %d\n", temperature, intTemp)
// 数値 → 文字列(2つの方法)
var code int = 65
char := string(rune(code)) // 方法1:対応するUnicode文字に変換 → "A"
numStr := fmt.Sprintf("%d", code) // 方法2:数値文字列に変換 → "65"
fmt.Printf("数値 %d → 文字: %s, 文字列: %q\n", code, char, numStr)
// --- 文字列とバイト/文字 ---
s := "Hello,世界"
fmt.Printf("\n文字列 %q の長さ: %d バイト\n", s, len(s))
fmt.Println("バイト単位の走査(CJKには推奨されません):")
for i := 0; i < len(s); i++ {
fmt.Printf(" [%d] %d %c\n", i, s[i], s[i])
}
fmt.Println("rune単位の走査(CJKを正しく処理):")
for i, r := range s {
fmt.Printf(" [%d] %U '%c'\n", i, r, r)
}
}
出力:
ユーザーロール: Admin (値: 2)
ユーザー権限値: 3 (バイナリ: 011)
読み取り権限あり? true
実行権限あり? false
体温: 36.6°C → 整数部分: 36
数値 65 → 文字: A, 文字列: "65"
文字列 "Hello,世界" の長さ: 12 バイト
バイト単位の走査(CJKには推奨されません):
[0] 72 H
[1] 101 e
[2] 108 l
[3] 108 l
[4] 111 o
[5] 44 ,
[6] 228 ä
[7] 184 ¸
[8] 150 \x96
[9] 228 ä
[10] 150 \x96
[11] 175 ¯
rune単位の走査(CJKを正しく処理):
[0] U+0048 'H'
[1] U+0065 'e'
[2] U+006C 'l'
[3] U+006C 'l'
[4] U+006F 'o'
[5] U+002C ','
[6] U+4E16 '世'
[7] U+754C '界'
要点:
iotaは0から開始し、行ごとに1ずつ自動インクリメントされるため、列挙型定数の定義に最適です。- ビット権限は
iotaの古典的な応用例です:|で権限を結合し、&で権限をチェックします。 int(float64)は小数部分を直接切り捨て、四捨五入しません。len(string)はバイト数を返し、文字数ではありません。CJK文字はUTF-8で3バイトを占めます。rangeを使って文字列をイテレーションすると、マルチバイト文字(rune)を正しく処理できます。
例3:総合応用(難易度⭐⭐⭐)
シナリオ: 変数、定数、型変換、フォーマット出力を組み合わせた、シンプルなユーザー登録情報処理システムをシミュレートします。
package main
import (
"fmt"
"strings"
)
// ========== 定数 ==========
// 性別列挙型
type Gender int
const (
Unknown Gender = iota // 0:不明
Male // 1:男性
Female // 2:女性
)
func (g Gender) String() string {
return [...]string{"Unknown", "Male", "Female"}[g]
}
// 会員レベルと対応する割引
const (
LevelBronze = 1
LevelSilver = 2
LevelGold = 3
LevelPlatinum = 4
)
// iotaで割引パーセンテージを生成
const (
_ = iota // 0をスキップ
DiscountBronze = 95 // 5%割引
DiscountSilver = 90 // 10%割引
DiscountGold = 85 // 15%割引
DiscountPlatinum = 80 // 20%割引
)
// ========== ユーザー構造体(プレビュー、詳細は後続レッスンで) ==========
type User struct {
Name string
Age int
Gender Gender
Level int
Balance float64
}
// ========== コアロジック ==========
func main() {
// シミュレーションデータ
users := []User{
{Name: "Li Ming", Age: 25, Gender: Male, Level: LevelGold, Balance: 1580.50},
{Name: "Wang Fang", Age: 30, Gender: Female, Level: LevelPlatinum, Balance: 3200.00},
{Name: "Zhang Wei", Age: 17, Gender: Male, Level: LevelBronze, Balance: 200.00},
{Name: "Zhao Min", Age: 22, Gender: Female, Level: LevelSilver, Balance: 800.75},
}
fmt.Println("╔══════════════════════════════════════════════════════════╗")
fmt.Println("║ ユーザー登録システム ║")
fmt.Println("╚══════════════════════════════════════════════════════════╝")
fmt.Println()
// 統計変数
var totalAge int
var totalBalance float64
var maleCount, femaleCount int
var adultCount int
for _, u := range users {
// 割引を取得
discount := getDiscount(u.Level)
discountAmount := u.Balance * float64(100-discount) / 100.0
// フォーマット出力
ageTag := ""
if u.Age >= 18 {
ageTag = "✅ 成人"
adultCount++
} else {
ageTag = "❌ 未成年"
}
fmt.Printf("👤 %-8s | 性別: %-6s | 年齢: %d (%s) | レベル: Lv.%d | 残高: $%.2f\n",
u.Name, u.Gender, u.Age, ageTag, u.Level, u.Balance)
fmt.Printf(" 💰 %d%%割引、$%.2f節約\n", discount, discountAmount)
// 統計
totalAge += u.Age
totalBalance += u.Balance
switch u.Gender {
case Male:
maleCount++
case Female:
femaleCount++
}
fmt.Println(strings.Repeat("-", 60))
}
// 統計を出力
avgAge := float64(totalAge) / float64(len(users))
fmt.Println()
fmt.Println("📊 統計:")
fmt.Printf(" 総ユーザー数: %d\n", len(users))
fmt.Printf(" 男性: %d | 女性: %d\n", maleCount, femaleCount)
fmt.Printf(" 成人: %d | 未成年: %d\n", adultCount, len(users)-adultCount)
fmt.Printf(" 平均年齢: %.1f歳\n", avgAge)
fmt.Printf(" 総残高: $%.2f\n", totalBalance)
fmt.Printf(" 平均残高: $%.2f\n", totalBalance/float64(len(users)))
// 型変換とフォーマットのデモ
fmt.Println()
fmt.Println("🔧 型変換デモ:")
demoTypeConversion()
}
// getDiscountは会員レベルに基づいて割引を返します
func getDiscount(level int) int {
switch level {
case LevelBronze:
return DiscountBronze
case LevelSilver:
return DiscountSilver
case LevelGold:
return DiscountGold
case LevelPlatinum:
return DiscountPlatinum
default:
return 100 // 割引なし
}
}
// demoTypeConversionは様々な型変換シナリオをデモンストレーションします
func demoTypeConversion() {
// 1. 数値型変換
var pi float64 = 3.14159
var intPi int = int(pi) // 切り捨て、四捨五入ではない
fmt.Printf(" float64 → int: %.5f → %d\n", pi, intPi)
// 2. 数値 → 文字列(2つの方法の比較)
var num int = 2024
way1 := string(rune(num)) // Unicode文字 → 想定とは異なる
way2 := fmt.Sprintf("%d", num) // 10進数文字列 → "2024"
way3 := fmt.Sprintf("%x", num) // 16進数文字列 → "7e8"
fmt.Printf(" int → string (rune): %q\n", way1)
fmt.Printf(" int → string (%%d): %q\n", way2)
fmt.Printf(" int → string (%%x): %q\n", way3)
// 3. 文字列 → 数値(fmt.Sscanfを使用)
var parsed int
_, err := fmt.Sscanf("12345", "%d", &parsed)
if err == nil {
fmt.Printf(" string → int (Sscanf): %d\n", parsed)
}
// 4. bool → 文字列
b := true
boolStr := fmt.Sprintf("%t", b)
fmt.Printf(" bool → string: %t → %q\n", b, boolStr)
// 5. runeとbyteの違い
var r rune = '中'
var b2 byte = 'A'
fmt.Printf(" rune '中': 値=%d, 16進=%U, %dバイト (UTF-8)\n", r, r, len(string(r)))
fmt.Printf(" byte 'A': 値=%d, 16進=%U, 1バイト\n", b2, b2)
}
出力:
╔══════════════════════════════════════════════════════════╗
║ ユーザー登録システム ║
╚══════════════════════════════════════════════════════════╝
👤 Li Ming | 性別: Male | 年齢: 25 (✅ 成人) | レベル: Lv.3 | 残高: $1580.50
💰 15%割引、$237.08節約
------------------------------------------------------------
👤 Wang Fang | 性別: Female | 年齢: 30 (✅ 成人) | レベル: Lv.4 | 残高: $3200.00
💰 20%割引、$640.00節約
------------------------------------------------------------
👤 Zhang Wei | 性別: Male | 年齢: 17 (❌ 未成年) | レベル: Lv.1 | 残高: $200.00
💰 5%割引、$10.00節約
------------------------------------------------------------
👤 Zhao Min | 性別: Female | 年齢: 22 (✅ 成人) | レベル: Lv.2 | 残高: $800.75
💰 10%割引、$80.08節約
------------------------------------------------------------
📊 統計:
総ユーザー数: 4
男性: 2 | 女性: 2
成人: 3 | 未成年: 1
平均年齢: 23.5歳
総残高: $5781.25
平均残高: $1445.31
🔧 型変換デモ:
float64 → int: 3.14159 → 3
int → string (rune): "\u07e8"
int → string (%d): "2024"
int → string (%x): "7e8"
string → int (Sscanf): 12345
bool → string: true → "true"
rune '中': 値=20013, 16進=U+4E16, 3バイト (UTF-8)
byte 'A': 値=65, 16進=U+0041, 1バイト
要点:
iotaを含む定数ブロックにより、列挙型やインクリメント値をエレガントに定義できます。- 型変換は明示的でなければなりません。Goは自動的に変換しません。
string(int)とfmt.Sprintf("%d", int)は完全に異なる効果があります — 前者はUnicode文字を生成し、後者は数値文字列を生成します。runeはUnicode文字の処理用、byteは単一バイトデータの処理用です。%qは文字列を引用符付きでフォーマットし、特殊文字をエスケープするため、デバッグに非常に便利です。
3. よくあるユースケース
ケース1:設定管理
package main
import "fmt"
// アプリケーション設定定数(コンパイル時に確定、不変)
const (
AppName = "GoWeb"
Version = "1.0.0"
MaxRetries = 3
DefaultTimeout = 30 // 秒
)
// 環境列挙型
type Env int
const (
Dev Env = iota // 開発
Staging // ステージング
Prod // 本番
)
func (e Env) String() string {
return [...]string{"Dev", "Staging", "Prod"}[e]
}
func main() {
// 実行時変数
currentEnv := Prod
dbHost := "192.168.1.100"
dbPort := 3306
debug := currentEnv == Dev
fmt.Printf("アプリ: %s v%s\n", AppName, Version)
fmt.Printf("環境: %s\n", currentEnv)
fmt.Printf("データベース: %s:%d\n", dbHost, dbPort)
fmt.Printf("デバッグモード: %t\n", debug)
fmt.Printf("最大リトライ: %d、タイムアウト: %d秒\n", MaxRetries, DefaultTimeout)
}
ケース2:データフォーマット&レポート
package main
import "fmt"
func main() {
// シミュレーション学生の成績データ
type Student struct {
Name string
Score float64
Grade string
}
students := []Student{
{"Alice", 92.5, ""},
{"Bob", 87.0, ""},
{"Charlie", 76.5, ""},
{"Diana", 95.0, ""},
{"Eve", 63.0, ""},
}
// 点数に基づいて自動的に成績を割り当て
for i := range students {
switch {
case students[i].Score >= 90:
students[i].Grade = "A (優秀)"
case students[i].Score >= 80:
students[i].Grade = "B (良好)"
case students[i].Score >= 70:
students[i].Grade = "C (平均)"
case students[i].Score >= 60:
students[i].Grade = "D (可)"
default:
students[i].Grade = "F (不可)"
}
}
// 成績レポートを出力
fmt.Println("┌─────────┬────────┬────────────┐")
fmt.Println("│ 名前 │ 点数 │ 成績 │")
fmt.Println("├─────────┼────────┼────────────┤")
var total float64
for _, s := range students {
fmt.Printf("│ %-7s │ %6.1f │ %-10s │\n", s.Name, s.Score, s.Grade)
total += s.Score
}
fmt.Println("├─────────┼────────┼────────────┤")
fmt.Printf("│ 平均 │ %6.1f │ │\n", total/float64(len(students)))
fmt.Println("└─────────┴────────┴────────────┘")
}
❓ よくある質問
質問1:varと:=のどちらを使うべきですか?(概念的な混乱)
回答: このシンプルな原則に従ってください:
| シナリオ | 推奨 | 理由 |
|---|---|---|
| 関数内で宣言と代入 | := |
より簡潔、Goコミュニティの慣例 |
| 関数内で代入なしの宣言 | var |
:=は代入が必要 |
| パッケージレベル変数 | var |
:=は関数外では使用不可 |
| 明示的な型指定が必要 | var |
予期しない型推論を回避 |
func example() {
// ✅ 推奨:関数内では := を使用
name := "Go"
count := 0
// ✅ var を使用:代入なしの宣言
var result string
if someCondition {
result = "yes"
} else {
result = "no"
}
// ✅ var を使用:正確な型が必要
var b byte = 255 // := だと int と推論される
}
質問2:なぜstring(65)は"65"と等しくないのですか?(よくある落とし穴)
回答: string(int)は整数をUnicodeコードポイントとして扱い、数値のテキスト表現としては扱いません:
// ❌ 誤った想定
s1 := string(65) // "65"を期待、実際は"A"(Unicode U+0041)
// ✅ 正しい方法
s2 := fmt.Sprintf("%d", 65) // "65"
s3 := strconv.Itoa(65) // "65"("strconv"のインポートが必要)
// string(rune)の実際の用途:Unicodeコードポイント → 文字
ch := string(rune(20013)) // "中" (U+4E16)
質問3:なぜlen("Hello,世界")は8ではないのですか?(よくある落とし穴)
回答: len()はバイト数を返し、文字数ではありません。Goの文字列はデフォルトでUTF-8エンコーディングを使用し、CJK文字はそれぞれ3バイトを占めます:
s := "Hello,世界"
fmt.Println(len(s)) // 12 (5 + 1 + 3×2 = 12バイト)
fmt.Println(utf8.RuneCountInString(s)) // 8 (5 + 1 + 2 = 8文字)
// 正しい文字数の数え方
count := 0
for range s {
count++
}
fmt.Println(count) // 8
質問4:2つの変数を素早くスワップするには?(実践的なヒント)
回答: Goは多重代入をサポートしており、1行のコードで実現できます:
a, b := 10, 20
a, b = b, a // スワップ:a=20, b=10
// 値を無視することも可能です
_, err := someFunction() // _を使って不要な戻り値を無視
📖 まとめ
- 変数宣言には2つの方法があります:
var(汎用的、関数外でも使用可能)と:=(簡潔、関数内のみ)。 - Goには豊富な基本型があります:
int/uint/float64/bool/string/byte/rune。 - ゼロ値メカニズムにより、変数は宣言後に常に明確な値を持ちます:数値は
0、ブール値はfalse、文字列は""、ポインタはnil。 constは定数を宣言し、iotaはconstブロック内で0から自動インクリメントされ、列挙型の定義に適しています。- Goは暗黙の型変換をサポートしません。異なる型は明示的に変換する必要があり、精度が失われる場合があります。
fmtパッケージはフォーマット出力の強力なツールです:Printlnで出力、Printfでフォーマット、Sprintfで文字列生成。len(string)はバイト数を返します。rangeで文字列をイテレーションすると、マルチバイト文字を正しく処理できます。string(int)は整数をUnicodeコードポイントとして扱い、数値テキスト変換ではありません。数値テキストにはfmt.Sprintfを使用してください。
📝 演習
演習1(⭐):変数とゼロ値
以下の変数を宣言し、そのゼロ値を出力してください:
int変数countfloat64変数pricebool変数activestring変数message
期待される出力:
count: 0
price: 0
active: false
message: ""
演習2(⭐⭐):iota列挙型と型変換
Color型(基本型int)を定義し、iotaを使って3つの色を定義してください:Red=0、Green=1、Blue=2。ColorにString()メソッドを実装してください。そして:
Color変数をGreenに設定し、その名前と値を出力してください。float64値3.14159をintに変換し、結果を出力してください(3になるはずです)。- 数値
2025を文字列"2025"に変換し、結果を出力してください。
演習3(⭐⭐⭐):温度変換ツール
以下のプログラムを書いてください:
- 定数
AbsoluteZeroC = -273.15(摂氏の絶対零度)を定義してください。 - 摂氏温度のセットを宣言してください:
-40, 0, 37, 100。 - 温度配列をイテレーションし、各摂氏温度を華氏に変換してください(式:
F = C × 9/5 + 32)。 - テーブル形式でフォーマット出力し、要件:
- 摂氏と華氏の温度を小数点以下1桁に丸める
- 温度が絶対零度以下かどうかを記載(物理的に不可能)
- 列幅を揃える
期待される出力:
┌─────────┬─────────┬────────────┐
│ 摂氏 │ 華氏 │ 状態 │
├─────────┼─────────┼────────────┤
│ -40.0 │ -40.0 │ 有効 │
│ 0.0 │ 32.0 │ 有効 │
│ 37.0 │ 98.6 │ 有効 │
│ 100.0 │ 212.0 │ 有効 │
└─────────┴─────────┴────────────┘
ヒント: const、var(配列/スライス)、forループ、fmt.Printfフォーマット、型変換(int ↔ float64)を使用してください。



