はじめに

GitHub Copilotは、AIを活用したコード補助ツールで、様々なプログラミング言語やフレームワークに対応しています。
本記事では、同じ内容の指示を日本語・英語・中国語でCopilotに与えた場合、どのように出力が異なるかを検証します。
iOS開発者として、特にSwiftのコード生成を例に取りながら比較します。

テスト環境と方法

  • 開発環境: VSCode + GitHub Copilotプラグイン(バージョン: 1.372.0)
  • 利用モデル: GPT-4.1 Copilot(gpt-41-copilot)
  • 言語: Swift(SwiftUI)
  • テスト内容: 以下の条件を満たすSwiftUIの商品管理画面を作成する指示を、日本語・英語・中国語でそれぞれ入力
    • 上部に商品名を入力するテキストフィールドと「商品追加」ボタンがある
    • 商品名を入力してボタンを押すと商品がリストに追加される
    • 空入力や重複入力の場合はエラー表示
    • 商品リストは削除可能
    • 各商品に「編集」ボタンがあり、商品名の変更が可能
    • 最大5件まで商品追加可能
  • 比較ポイント: コードの完成度、UIのエラー表示方法、コメントの有無、コードの読みやすさなど

生成コードの概要と違い

コード全文は長いため割愛し、各言語で特徴的な部分を抜粋し比較します。

 日本語版

アラート表示部分

エラー時は以下のように呼び出す

  • エラー表示は標準のモーダルアラートを使用
  • 変数名・関数名も日本語に適した命名(例:showAlertMsg)
  • コード本体がわかりやすい設計

英語版

アラート表示部分

エラー時は以下のように呼び出す

  • 日本語版とほぼ同じエラー表示(モーダルアラート)
  • 関数名・変数名も英語で自然に命名
  • コードロジック・UI構造は非常に似ている

中国語版


エラーは画面内テキストで表示

エラー表示用関数

  • モーダルアラートではなく、画面上に赤文字でエラーメッセージを表示するUI設計
  • 変数名や関数名も「Error」を使うなどUIロジックに合わせた命名
  • エラーメッセージの表示方法が一番異なるポイント


比較と考察

  • 英語版は日本語版とほぼ差異がなく、Copilotが言語間で同様の出力を行っていることがわかる
  • 中国語版はエラー表示UIの設計思想が異なり、モーダルを使わず画面内表示を選択。これがコード全体の雰囲気やユーザビリティに影響を与えている
  • 中国語版はエラーの見せ方を簡潔にしており、結果として「コード本体に重きを置く」という印象を受けた可能性がある
  • 変数名・関数名はそれぞれの言語の慣習に従い、自然な命名がされている

おわりに

今回の比較を通じて、多言語での指示がGitHub Copilotのアウトプットに細かな違いをもたらすことがわかりました。
特にエラー表示のUI設計や関数命名において、言語圏ごとの特徴が反映されていました。
iOS開発者としては、英語の活用をベースにしつつ、必要に応じて日本語や中国語の指示も試し、ツールの特性を活かすことが望ましいでしょう。
今後もAIツールをうまく活用し、開発効率をさらに高めていきたいと思います。

追加資料:コード全文

日本語の完全版コード

import SwiftUI

struct ProductManagerView: View {
	@State private var products: [String] = []
	@State private var inputText: String = ""
	@State private var showAlert: Bool = false
	@State private var alertMessage: String = ""
	@State private var editingIndex: Int? = nil
	@State private var editingText: String = ""

	var body: some View {
		VStack(alignment: .leading, spacing: 16) {
			HStack {
				TextField("商品名を入力", text: $inputText)
					.textFieldStyle(RoundedBorderTextFieldStyle())
					.frame(maxWidth: 200)
				Button("商品追加") {
					addProduct()
				}
				.disabled(products.count >= 5)
			}
			.padding(.top)

			Text("商品リスト(\(products.count)/5):")
				.font(.headline)
			List {
				ForEach(products.indices, id: \ .self) { idx in
					HStack {
						if editingIndex == idx {
							TextField("商品名", text: $editingText)
								.textFieldStyle(RoundedBorderTextFieldStyle())
							Button("保存") {
								saveEdit(idx: idx)
							}
							Button("キャンセル") {
								editingIndex = nil
								editingText = ""
							}
						} else {
							Text(products[idx])
							Spacer()
							Button("編集") {
								editingIndex = idx
								editingText = products[idx]
							}
						}
					}
				}
				.onDelete(perform: deleteProduct)
			}
			.frame(maxHeight: 300)
		}
		.padding()
		.alert(isPresented: $showAlert) {
			Alert(title: Text("エラー"), message: Text(alertMessage), dismissButton: .default(Text("OK")))
		}
	}

	private func addProduct() {
		let trimmed = inputText.trimmingCharacters(in: .whitespacesAndNewlines)
		guard !trimmed.isEmpty else {
			showAlertMsg("商品名を入力してください")
			return
		}
		guard !products.contains(trimmed) else {
			showAlertMsg("同じ商品名が既に存在します")
			return
		}
		guard products.count < 5 else {
			showAlertMsg("商品は最大5件までです")
			return
		}
		products.append(trimmed)
		inputText = ""
	}

	private func deleteProduct(at offsets: IndexSet) {
		products.remove(atOffsets: offsets)
		if let idx = editingIndex, offsets.contains(idx) {
			editingIndex = nil
			editingText = ""
		}
	}

	private func saveEdit(idx: Int) {
		let trimmed = editingText.trimmingCharacters(in: .whitespacesAndNewlines)
		guard !trimmed.isEmpty else {
			showAlertMsg("商品名を入力してください")
			return
		}
		if products.contains(trimmed) && products[idx] != trimmed {
			showAlertMsg("同じ商品名が既に存在します")
			return
		}
		products[idx] = trimmed
		editingIndex = nil
		editingText = ""
	}

	private func showAlertMsg(_ msg: String) {
		alertMessage = msg
		showAlert = true
	}
}

struct ProductManagerView_Previews: PreviewProvider {
	static var previews: some View {
		ProductManagerView()
	}
}

英語版のコードは日本語版とほぼ同一のため、掲載を省略しています。

中国語の完全版コード

import SwiftUI

struct ProductManagerView: View {
    @State private var products: [String] = []
    @State private var inputText: String = ""
    @State private var showError: Bool = false
    @State private var errorMessage: String = ""
    @State private var editingIndex: Int? = nil
    @State private var editingText: String = ""

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            HStack {
                TextField("请输入商品名", text: $inputText)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .frame(maxWidth: 200)
                Button("添加商品") {
                    addProduct()
                }
                .disabled(products.count >= 5)
            }
            .padding(.top)

            if showError {
                Text(errorMessage)
                    .foregroundColor(.red)
            }

            Text("商品列表(\(products.count)/5):")
                .font(.headline)
            List {
                ForEach(products.indices, id: \ .self) { idx in
                    HStack {
                        if editingIndex == idx {
                            TextField("商品名", text: $editingText)
                                .textFieldStyle(RoundedBorderTextFieldStyle())
                            Button("保存") {
                                saveEdit(idx: idx)
                            }
                            Button("取消") {
                                editingIndex = nil
                                editingText = ""
                            }
                        } else {
                            Text(products[idx])
                            Spacer()
                            Button("编辑") {
                                editingIndex = idx
                                editingText = products[idx]
                            }
                        }
                    }
                }
                .onDelete(perform: deleteProduct)
            }
            .frame(maxHeight: 300)
        }
        .padding()
    }

    private func addProduct() {
        let trimmed = inputText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else {
            showErrorMsg("商品名不能为空")
            return
        }
        guard !products.contains(trimmed) else {
            showErrorMsg("商品已存在")
            return
        }
        guard products.count < 5 else {
            showErrorMsg("最多只能添加5个商品")
            return
        }
        products.append(trimmed)
        inputText = ""
        showError = false
    }

    private func deleteProduct(at offsets: IndexSet) {
        products.remove(atOffsets: offsets)
        if let idx = editingIndex, offsets.contains(idx) {
            editingIndex = nil
            editingText = ""
        }
    }

    private func saveEdit(idx: Int) {
        let trimmed = editingText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else {
            showErrorMsg("商品名不能为空")
            return
        }
        if products.contains(trimmed) && products[idx] != trimmed {
            showErrorMsg("商品已存在")
            return
        }
        products[idx] = trimmed
        editingIndex = nil
        editingText = ""
        showError = false
    }

    private func showErrorMsg(_ msg: String) {
        errorMessage = msg
        showError = true
    }
}

struct ProductManagerView_Previews: PreviewProvider {
    static var previews: some View {
        ProductManagerView()
    }
}


ギャップロを運営しているアップフロンティア株式会社では、一緒に働いてくれる仲間を随時、募集しています。 興味がある!一緒に働いてみたい!という方は下記よりご応募お待ちしております。
採用情報をみる