Skip to content

Instantly share code, notes, and snippets.

@mebiusbox
Last active May 12, 2025 16:09
Show Gist options
  • Save mebiusbox/ba33ca2d3ae5d7d847593942dcbb14d4 to your computer and use it in GitHub Desktop.
Save mebiusbox/ba33ca2d3ae5d7d847593942dcbb14d4 to your computer and use it in GitHub Desktop.
marp
# https://editorconfig.org/
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
end_of_line = crlf
insert_final_newline = true
trim_trailing_whitespace = true
# max_line_length = 119
# https://learn.microsoft.com/en-us/visualstudio/ide/cpp-editorconfig-properties?view=vs-2022
[*.{c,cpp,cxx,h,hxx,inl,glsl,hlsl,rs}]
# curly_bracket_next_line = false
[*.{lua,bat,cmd}]
indent_size = 2
[*.{cs,csx,vb,vbx}]
charset = utf-8-bom
[*.{ps1,psd1,psm1}]
[*.md]
# 環境によって末尾の空白2つで改行扱いするものがある
trim_trailing_whitespace = false
[*.py]
indent_size = 2
[*.{htm,html,tsx,xml,css,scss,sass,less,js,ts,yml,yaml,toml,json}]
indent_size = 2
[*.{yml,yaml}]
trim_trailing_whitespace = false
indent_size = 2
[*.txt]
insert_final_newline = false
[*.{tex,sty}]
#--------------------------------------------------------------------
# insert_final_newline, trim_trailing_whitespace が反映されない場合、
# Visual Studio Code 側の設定を確認すること.
# - files.insertFinalNewLine
# - files.trimTrailingWhitespace
# - editor.trimAutoWhitespace
# Visual Studio Code のEditorConfig拡張機能では以下の項目は保存時:
# - end_of_line
# - insert_final_newline
# - trim_trailing_whitespace
#--------------------------------------------------------------------
[*.{cs,csx}]
# https://learn.microsoft.com/ja-jp/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options
# New Line Options
csharp_new_line_before_open_brace = none # "{"を新しい行に配置するか
csharp_new_line_before_else = false # "else"を新しい行に配置するか
csharp_new_line_before_catch = false # "catch"を新しい行に配置するか
csharp_new_line_before_finally = false # "finally"を新しい行に配置するか
csharp_new_line_before_members_in_object_initializers = true # オブジェクト初期化子のメンバーを別の行に配置するか
csharp_new_line_before_members_in_anonymous_types = true # 匿名型のメンバーを別の行に配置するか
csharp_new_line_between_query_expression_clauses = true # クエリ式の句の要素を別の行に配置するか
# Indentation Options
csharp_indent_block_contents = true # ブロックの内容をインデントするか
csharp_indent_braces = false # "{}"をインデントするか
csharp_indent_switch_labels = false # "switch" ラベルにインデントを付けるか
csharp_indent_case_contents = true # "switch" ケースにインデントを付けるか
csharp_indent_case_contents_when_block = false # "switch" ケースでのブロックをインデントするか
csharp_indent_labels = one_less_than_current # ラベルの配置位置
# Spacing Options
csharp_space_before_comma = false # コンマの前
csharp_space_after_comma = true # コンマの後
csharp_space_before_dot = false # ドットの前
csharp_space_after_dot = false # ドットの後
csharp_space_between_parentheses = false # "()"間
csharp_space_around_binary_operators = before_and_after # バイナリ演算子の前後
csharp_space_before_open_square_brackets = false # "["の前
csharp_space_between_square_brackets = false # "[]"の間
csharp_space_between_empty_square_brackets = false # 空の"[]"の間
csharp_space_after_cast = false # キャストの間
csharp_space_after_keywords_in_control_flow_statements = true # 制御フローステートメント(forなど)の後
csharp_space_before_semicolon_in_for_statement = false # forステートメントのセミコロンの前
csharp_space_after_semicolon_in_for_statement = true # forステートメントのセミコロンの後
csharp_space_around_declaration_statements = false # 宣言ステートメントの余計な空白文字. "false"なら削除
csharp_space_between_method_declaration_name_and_open_parenthesis = false # メソッド宣言のメソッド名と始め括弧の間
csharp_space_between_method_declaration_parameter_list_parentheses = false # メソッド宣言パラメータのリスト始めと終わり
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false # メソッド宣言の空パラメータのリスト始めと終わり
csharp_space_between_method_call_name_and_opening_parenthesis = false # メソッド呼び出し名と始め括弧の間
csharp_space_between_method_call_parameter_list_parentheses = false # メソッド呼び出しの始め括弧と終わり括弧
csharp_space_between_method_call_empty_parameter_list_parentheses = false # 空パラメータのメソッド呼び出しの始め括弧と終わり括弧
csharp_space_before_colon_in_inheritance_clause = true # 型宣言の":"前
csharp_space_after_colon_in_inheritance_clause = true # 型宣言の":"後
# Wrap Options
csharp_preserve_single_line_statements = false # 1行に複数のステートメントとメンバー宣言を表示
csharp_preserve_single_line_blocks = true # コードブロックを単一行に配置
# diagnostic
dotnet_diagnostic.IDE0044.severity = none # Make field read-only
dotnet_diagnostic.RCS1169.severity = none # Make field read-only
dotnet_diagnostic.IDE0051.severity = none # Remove unused member declaration
dotnet_diagnostic.RCS1213.severity = none # Remove unused member declaration
dotnet_diagnostic.SA1500.severity = none # Braces for Multi-Line Statements must not share line
dotnet_diagnostic.SA1633.severity = none # The file header is missing or not located at the top of the file
# .NET Coding Conventions
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = true:suggestion
dotnet_style_qualification_for_field = true:suggestion
dotnet_style_qualification_for_method = true:suggestion
dotnet_style_qualification_for_property = true:suggestion
# Naming Styles
dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.camel_case_and_prefix_with_underscore.required_prefix = _
dotnet_naming_style.camel_case_and_prefix_with_underscore.capitalization = camel_case
dotnet_naming_style.pascal_case_and_prefix_with_I.required_prefix = I
dotnet_naming_style.pascal_case_and_prefix_with_I.capitalization = pascal_case
dotnet_naming_style.pascal_case_and_prefix_with_T.required_prefix = T
dotnet_naming_style.pascal_case_and_prefix_with_T.capitalization = pascal_case
# Naming Symbols
# Interfaces
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = *
# Type parameters
dotnet_naming_symbols.type_parameter_symbols.applicable_kinds = type_parameter
dotnet_naming_symbols.type_parameter_symbols.applicable_accessibilities = *
# Constants
dotnet_naming_symbols.constant.applicable_kinds = field
dotnet_naming_symbols.constant.required_modifiers = const
dotnet_naming_symbols.constant.applicable_accessibilities = *
# Pascal most of the things
dotnet_naming_symbols.pascal.applicable_kinds = class, struct, enum, property, method, event, namespace, delegate, local_function
dotnet_naming_symbols.pascal.applicable_accessibilities = *
# Parameters, locals
dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
dotnet_naming_symbols.locals_and_parameters.applicable_accessibilities = *
# Private fields
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
# Public fields
dotnet_naming_symbols.public_field.applicable_kinds = field
dotnet_naming_symbols.public_field.applicable_accessibilities = public, internal, friend, protected, protected_internal, protected_friend, private_protected
# Naming Rules
# Interfaces
dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.symbols = interface
dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.style = pascal_case_and_prefix_with_I
dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.severity = warning
# Type parameters
dotnet_naming_rule.type_parameters_must_be_pascal_cased_and_prefixed_with_T.symbols = type_parameter
dotnet_naming_rule.type_parameters_must_be_pascal_cased_and_prefixed_with_T.style = pascal_case_and_prefix_with_T
dotnet_naming_rule.type_parameters_must_be_pascal_cased_and_prefixed_with_T.severity = warning
# Pascal most of the things
dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.symbols = pascal
dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.style = pascal_case
dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.severity = warning
# Parameters, locals
dotnet_naming_rule.parameters_must_be_camel_cased.symbols = locals_and_parameters
dotnet_naming_rule.parameters_must_be_camel_cased.style = camel_case
dotnet_naming_rule.parameters_must_be_camel_cased.severity = warning
# Constants
dotnet_naming_rule.constants_must_be_pascal_cased.symbols = constant
dotnet_naming_rule.constants_must_be_pascal_cased.style = pascal_case
dotnet_naming_rule.constants_must_be_pascal_cased.severity = warning
# Public fields
dotnet_naming_rule.public_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.symbols = public_field
dotnet_naming_rule.public_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.style = pascal_case
dotnet_naming_rule.public_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.severity = warning
# Private fields
dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.symbols = private_or_internal_field
dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.style = camel_case_and_prefix_with_underscore
dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.severity = warning
.gisttool
.vscode
*.pdf
_*.css
MD013: false # line-length
MD024: false # no-duplicate-heading
MD025: true # single-title/single-h1
MD041: false # first-line-heading/first-line-h1
MD033: false # no-inline-html
MD040: true # fenced-code-language
MD046: true # code-block-style
MD048: false # code-fence-style
list-marker-space:
ul_multi: 3
ul_single: 3
ul-indent:
indent: 4
# 文字数の制限 (default: 80)
printWidth: 119
# 末尾のコロンを削除するかどうか. ["all", "es5", "none"]
trailingComma: "all"
# タブを使うかどうか (.editorconfig)
# useTabs: true
# タブサイズ (.editorconfig)
# tabWidth: 4
# 末尾にセミコロンを付与するか
semi: true
# シングルクォートを使うか
singleQuote: false
# ブラケットの間にスペースを入れるかどうか
bracketSpacing: true
# 閉ブラケットを新規行にするかどうか
bracketSameLine: false

Marp

Template

---
marp: true
title: hoge
class:
  # - invert
  # - lead
size: 16:9
theme: default
paginate: true
---
<!-- markdownlint-disable MD025 -->

Tips

Markdown Preview Enhanced

Markdown Preview Enhancedでは表示されないので、Marpは標準のMarkdownビューアを使う必要がある.

Pixy theme

カスタムテーマを使う場合は .vscode/settings.json に以下を追加する.

{
  "markdown.marp.themes": [
    "./marp-pixy.css"
  ]
}

Example

---
marp: true
title: test
size: 16:9
theme: pixy
paginate: true
class:
  # - invert
  # - decorate
  # - lead
  # - full
---

# Default
...

# Advanced
<!-- _class: advanced -->
...

# Highlight
<!-- _class: highlight -->
...

# Lead + Invert
<!-- _class: lead invert -->
...

# Full + Invert
<!-- _class: full invert -->
表示する領域が大きい(フォントサイズやマージンが小さい)
@font-family-base: Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea",
"UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
@font-family-mono: "Sarasa Fixed J", "Iosevka Fixed", "Inconsolata", "Fira Mono", Consolas, "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", monospace;
@font-family-serif: "Merriweather", "PT Serif", "Times New Roman", Times,
"UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
@font-size-base: 1.5em;
@font-size-sm: 1.4em;
@font-size-xs: 1.3em;
@font-size-head: 2.2em;
@font-size-lead: 3.0em;
@font-size-list-1: 1.2em;
@font-size-list-2: 0.85em;
@font-size-code: 0.9em;
@line-height-base: 1.6em;
@line-height-sm: 1.5em;
@line-height-xs: 1.4em;
@color-foreground: #eee;
@color-background: #242424;
@color-primary: #ffcc00;
@color-primary-light: #ffd11a;
@color-primary-lighter: #ffd426;
@color-primary-lightest: #ffdb4d;
@color-primary-dark: #e6b800;
@color-primary-darker: #d9ad00;
@color-primary-darkest: #b38f00;
@color-secondary: #ebedf0;
@color-secondary-dark: #d4d5d8;
@color-secondary-darker: #c8c9cc;
@color-secondary-darkest: #a4a6a8;
@color-secondary-light: #eef0f2;
@color-secondary-lighter: #f1f2f5;
@color-secondary-lightest: #f5f6f8;
@color-heading-1: @color-primary;
@color-heading-2: @color-primary;
@color-heading-3: #0cf;
@color-secondary: #ebedf0;
@color-highlight: #b92a2c;
@color-success: #00a400;
@color-info: #0cf;
@color-warning: #ffba00;
@color-danger: #fa383e;
@color-table-background: #272822;
@color-table-foreground: @color-foreground;
@color-table-head-background: #444;
@color-table-head-foreground: @color-foreground;
@color-table-head-row-background: #444;
@color-table-head-row-foreground: @color-info;
@color-foreground: #282c2f;
@color-background: #eee;
@color-primary: #3578f6;
@color-primary-light: #528bf7;
@color-primary-lighter: #6095f8;
@color-primary-lightest: #8bb1fa;
@color-primary-dark: #1865f5;
@color-primary-darker: #0b5cf3;
@color-primary-darkest: #094bc8;
@color-secondary: #ebedf0;
@color-secondary-dark: #d4d5d8;
@color-secondary-darker: #c8c9cc;
@color-secondary-darkest: #a4a6a8;
@color-secondary-light: #eef0f2;
@color-secondary-lighter: #f1f2f5;
@color-secondary-lightest: #f5f6f8;
@color-heading-1: @color-primary;
@color-heading-2: @color-primary;
@color-heading-3: #d21a4e;
@color-secondary: #ebedf0;
@color-highlight: #b92a2c;
@color-success: #00a400;
@color-info: #0cf;
@color-warning: #ffba00;
@color-danger: #fa383e;
@color-table-background: #444;
@color-table-foreground: #eee;
@color-table-head-background: #444;
@color-table-head-foreground: #eee;
@color-table-head-row-background: #444;
@color-table-head-row-foreground: #eee;
@font-family-base: Gudea, "UD デジタル 教科書体 NK-R", Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
@font-family-mono: "Iosevka Fixed", "Inconsolata", "Fira Mono", "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
@font-family-serif: "Merriweather", "PT Serif", "Times New Roman", Times,
"UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
@font-size-base: 1.4em;
@font-size-sm: 1.3em;
@font-size-xs: 1.2em;
@font-size-head: 2.0em;
@font-size-head-sm: 1.8em;
@font-size-head-xs: 1.6em;
@font-size-lead: 2.6em;
@font-size-lead-sm: 2.4em;
@font-size-lead-xs: 2.0em;
@font-size-list-1: 1.2em;
@font-size-list-2: 0.85em;
@font-size-code: 0.7rem;
@line-height: 1.6em;
@line-height-sm: 1.5em;
@line-height-xs: 1.4em;
marp title size theme paginate math
true
C# Programming Language
58140
pixy-prog
true
katex

The C# Programming Language


C#とは

  • Microsoftが開発したプログラミング言語.
  • 共通中間言語(CIL: Common Intermediate Language)に変換し、共通言語基盤(CLI: Common Language Infrastructure)で動作する.
  • CLI として .NET Framework がある.

Version

言語バージョン リリース .NET Visual Studio
C# 7.0 2017/3 .NET Framework 4.7 Visual Studio 2019 version 16.8
C# 8.0 2019/9 .NET Core 3.0,3.1 Visual Studio 2019 version 16.8
C# 9.0 2020/11 .NET 5.0 Visual Studio 2019 version 16.8
C# 10.0 2021/11 .NET 6.0 Visual Studio 2022 version 17.0
C# 11.0 2022/11 .NET 7.0 Visual Studio 2022 version 17.4
C# 12.0 2023/11 .NET 8.0 Visual Studio 2022 version 17.8
C# 13.0 2024/11 .NET 9.0 Visual Studio 2022 version 17.12

データ型

説明
sbyte, int, short, long 符号あり整数
byte, uint, ushort, ulong 符号なし整数
float, double 浮動小数点
char 単一Unicode文字
bool 論理ブール
object すべての基本型
string 文字列
decimal 10進数(29の有効桁数)

null

  • 無効(初期化されていない値)を表す.

null許容型(C# 2.0)

  • 通常、値型は null を取れません.しかし、データベースなどで null を許容したい場合があります.その場合 null許容型(Nullable型) を利用できます.
  • null許容型は値型の後ろに ? を付けます.
int? x = 123;
int? y = null;
  • C# 8.0 から参照にたいしても null許容型を指定できるようになりました.?を指定すればnull許容型、指定しなければnull非許容型となります.

null合体演算子 (C# 2.0)

  • null許容型には ?? 演算が使えます.これは、null合体演算子と呼ばれ、値が null かどうかを判定します.
// x, y は int? 型の変数
int? z = x ?? y; // x != null ? x : y
int i = z ?? -1; // z != null ? z.Value : -1

null合体代入演算子 (C# 8.0)

  • null合体代入(??=)が使えるようになりました.
static void M(string s = null) {
    s ??= "default string";
    Console.WriteLine(s);
}

null条件演算子 (C# 6.0)

  • null だったら null を返す処理を簡潔に書くための演算子が追加されました.
static string M(Weapon w) => w?.ImagePath;
static char? Write(string s, int i) => s?[i];

const, readonly

  • 定数の定義に使う.定数は宣言時に値をリテラルで初期化できるものしか使えません(newは使えない).
  • 他に readonly 変数というのがあって、const は値が将来的にも不変のときに使います.それ以外なら readonly を使います.

for

for ( 初期化処理 ; 条件式 ; 増分処理 ) {
    処理
}

while

while (条件式) {
    処理
}

do-while

do {
    処理
} while (条件式);

foreach

foreach(変数 in 配列変数)

アクセス指定子

アクセス指定子 意味
public どこからでもアクセスできる。
protected 同一クラスか、そのサブクラスからしか呼び出せない。
internal 同一のアセンブリ(DLL)内でアクセスが可能。
protected internal protectedcted かつ internal。
private 同じクラス内からしか呼び出せない。

プロパティ

アクセスレベル 型名 プロパティ名 {
    set {
        // setアクセサー(setter とも言う)
        //  ここに値の変更時の処理を書く。
        //  value という名前の変数に代入された値が格納される。
    }
    get {
        // getアクセサー (getter とも言う)
        //  ここに値の取得時の処理を書く。
        //  メソッドの場合と同様に、値はreturnキーワードを用いて返す。
    }
}

自動プロパティ (C# 3.0)

  • C# 3.0 から自動プロパティが追加され、省略できます.
class Sample {
    public int X { get; private set; }
    public Sample(int x) { X = x; }
}

不変プロパティ (C# 6.0)

  • C# 6.0 から不変プロパティのために get-only プロパティが追加されました.
class Sample {
    public int X { get; }
    public Sample(int x) { X = x; }
}

プロパティの初期値

  • コンストラクタ内、もしくは初期値で設定できます.
class Sample {
    public int X { get; } = 10;
}

プロパティ(インデックス版)

アクセスレベル 戻り値の型 this[添字の型 添字] {
  set {
    // setアクセサ
    //  ここに値の変更時の処理を書く。
    //  value という名前の変数に代入された値が格納される。
    //  添字が使える以外はプロパティと同じ。
  }
  get {
    // getアクセサ
    //  ここに値の取得時の処理を書く。
    //  メソッドの場合と同様に、値はreturnキーワードを用いて返す。
    //  こっちも添字が使える以外はプロパティと同じ。
  }
}

関数

戻り値の型 関数名(引数リスト) {
    ...
}

関数 (C# 6.0)

  • C# 6.0 から、関数本体が1つの式だけからなる場合、以下のように簡潔に書けるようになりました.
int Hoge(int a, int b) => return a+b;

タプル (C# 7.0)

  • タプルは System.ValueTuple型.
class Sample {
    private (int x, int y) value;
    public (int x, int y) GetValue() => value;
}
  • 次のようにタプルリテラルを書けます
(int x, int y) t1 = (1, 2);
  • タプルはメンバーで参照したり、分解代入できます.

匿名タプル

static (int sum, int count) Tally(int[] items) {
    var sum = 0;
    var count = 0;
    foreach (var x in items) {
        sum += x;
        count++;
    }
    return (sum, count); // 匿名タプル
}

匿名関数(ラムダ関数)(C# 3.0)

  • C# 2.0 では次のように書いていたコード
delegate(int n){ return n > 10; }
  • これは C# 3.0 の匿名関数(ラムダ式)だと次のように書けます
(int n) => { return n > 10; }
  • さらに return 式だけなら、以下のように書けます
(int n) => n > 10;

匿名関数(ラムダ関数)(C# 10.0)

  • また、C# 10.0 から属性や戻り値の型が指定できるようになりました.
var f = [A] static int? ([A] string? s) => s?.Length;
  • これだと型推論ができるので var が使えます.

可変長引数のキーワード: params

class ParamsTest {
  static void Main() {
    int a = 314, b = 159, c = 265, d = 358, e  = 979;
    // ↑これらの最大値を探したいとき、

    int max = Max(a, b, c, d, e);
    // ↑こうすると、自動的に配列を作って値を格納してくれる。

    Console.Write("{0}\n", max);
  }

  static int Max(params int[] a) {
    int max = a[0];
    for(int i=1; i<a.Length; ++i) {
      if(max < a[i])
        max = a[i];
    }
    return max;
  }
}

オプション引数

static int Sum(int x = 0, int y = 0, int z = 0) {
  return x + y + z;
}
int s1 = Sum();     // Sum(0, 0, 0); と同じ意味。
int s2 = Sum(1);    // Sum(1, 0, 0); と同じ意味。
int s3 = Sum(1, 2); // Sum(1, 2, 0); と同じ意味。

名前付き引数

int s1 = Sum(x: 1, y: 2, z: 3); // Sum(1, 2, 3); と同じ意味。
int s2 = Sum(y: 1, z: 2, x: 3); // Sum(3, 1, 2); と同じ意味。
int s3 = Sum(y: 1);             // Sum(0, 1, 0); と同じ意味。

参照渡し

  • 値渡しの場合、完全なコピーが渡されます.参照の場合は、元のオブジェクトに影響します.
  • 参照渡しをするには ref キーワードを使います.また、out キーワードを使えば、関数からの返り値として特別な参照を受け取れます.C# 7.0 から out キーワードと一緒に型を指定すると変数宣言ができます.
  • 他に、in キーワード(C# 7.2)を使えば、参照渡しだけど、読み取り専用になります.

オブジェクト初期化子 (C# 3.0)

Point p = new Point{ X = 0, Y = 1 };

is演算子

  • is 演算子はキャスト可能かどうかを調べるための演算子
変数名 is 型名
  • C# 7.0 から以下のような書き方も可能になりました.
static void TypeSwitch(object obj) {
    // C# 7での新しい書き方
    if (obj is string s)  {
        Console.WriteLine("string #" + s.Length);
    }
}

as演算子

  • as 演算子はキャストと同じような働きをする演算子
変換先の変数 = 変換元の変数 as 型名
  • as演算子はキャストできない場合、nullを返す.

コレクション

Class Description Generics
ArrayList 配列 List
Hashtable 連想配列 Dictionarly
marp title size theme paginate footer math
true
Go Programming Language
58140
pixy-prog
true
mebiusbox2
katex

The Go Programming Language


Basics


Packages

  • Every Go program is made up of packages.
  • Programs start running in package main.
package main
import (
    "fmt"
    "math/rand"
)
func main() {
    fmt.Println("My favorite number is", rand.Intn(10))
}

Imports

  • This code groups the imports into a parenthesized, factored import statement.
package main
import (
    "fmt"
    "math"
)
func main() {
    fmt.Printf("Now you have %g problems.\n", math.Sqrt(7))
}

Exported names

  • In Go, a name is exported if it begins with a capital letter. For example, Pizza is an exported name, as is Pi, which is exported from the math package.
  • When importing a package, you can refer only to its exported names. Any "unexported" names are not accessible from outside the package.

Functions

  • A function can take zero or more arguments.
  • Notice that the type comes after the variable name.
  • When two or more consecutive named function parameters share a type, you can omit the type from all but the last. x int, y int → x, y int

Multiple results

  • A function can return any number of results.
func swap(x, y string) (string, string) {
    return y, x
}
func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}

Named return values

  • Go's return values may be named. If so, they are treated as variables defined at the top of the function.
  • These names should be used to document the meaning of the return values.
  • A return statement without arguments returns the named return values. This is known as a "naked" return.
  • Naked return statements should be used only in short functions, as with the example shows here. They can harm readability in longer functions.

Named return values (2)

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}
func main() {
    fmt.Println(split(17))
}

Variables

  • The var statement declares a list of variables; as in function argument lists, the type is last.
  • A var statement can be at package or function level.
var c, python, java bool
func main() {
    var i int
    fmt.Println(i, c, python, java)
}

Variables with initializers

  • A var declaration can include initializers, one per variable.
  • If an initializer is present, the type can be omitted; the variable will take the type of the initializer.
var i, j int = 1, 2
func main() {
    var c, python, java = true, false, "no!"
    fmt.Println(i, j, c, python, java)
}

Short variable declarations

  • Inside a function, the := short assignment statement can be used in place of a var declaration with implicit type.
  • Outside a function, every statement begins with a keyward (var, func, and so on) and so the := construct is not available.
func main() {
    var i, j int = 1, 2
    k := 3
    c, python, java := true, false, "no!"
    fmt.Println(i, j, k, c, python, java)
}

Basic Types

  • Go's basic types are:
    • bool
    • int, int8, int16, int32, int64
    • uint, uint8, uint16, uint32, uint64
    • byte (alias for uint8)
    • rune (alias for int32, represents a Unicode code point)
    • float32, float64
    • complex64, complex128

Zero values

  • Variables declared without an explicit initial value are given their zero value.
  • The zero value is:
    • 0 for numeric types
    • false for the boolean type
    • "" (the empty string) for strings

Type conversions

  • The expression T(v) converts the value v to the type T.
  • Unlike in C, in Go assignment between items of different type requires an explicit conversion.
func main() {
    var x, y int = 3, 4
    var f float64 = math.Sqrt(float64(x*x + y*Y))
    var z uint = uint(f)
    fmt.Println(x, y, z)
}

Type inference

  • When declaring a variable without sepcifiying an explicit type (either by using the := syntax or var = expression syntax), the variable's type is inferred from the value on the right hand side.
  • When the right hand side of the declaration is typed, the new variable is of that same type:
var i int
j := i // j is an int

Constants

  • Constants are declared like variables, but with the const keyword.
  • Constants can be character, string, boolean, or numeric values.
  • Constants cannot be declared using the := syntax.
const Pi = 3.14
func main() {
    const World = "世界"
    fmt.Println("Hello", World)
    fmt.Println("Happy", Pi, "Day")
    const Truth = true
    fmt.Println("Go rules?", Truth)
}

For

  • Go has only one looping construct, the for loop.
  • The basic for loop has three components separated by semicolons:
    • The init statement: executed before the first iteration.
    • The condition expression: evaluated before every iteration.
    • The post statement: executed at the end of every iteration.
  • Note: Unlike other languages like C, Java, or JavaScript there are no parenthes surroudning the three components of the for statement and the braces {} are always required.

For (2)

  • The init and post statements are optional.
sum := 0
for i := 0; i < 10; i++ {
    sum += i
}

sum := 1
for ; sum < 1000; {
    sum += sum
}

For is Go's "while"

  • At that point you can drop the semicolons: C's while is spelled for in Go.
func main() {
    sum := 1
    for sum < 1000 {
        sum += sum
    }
    fmt.Println(sum)
}

Forever

  • If you omit the loop condition it loops forever, so an infinite loop is compactly expressed.
func main() {
    for {
    }
}

If

  • Go's if statements are like its for loops; the expression need not be surrounded by parenthes () but the braces {} are required.
func sqrt(x float64) string {
    if x < 0 {
        return sqrt(-x) + "i"
    }
    return fmt.Sprint(math.Sqrt(x))
}

If with a short statement

  • Like for, the if statement can start with a short statement to execute before the condition.
  • Variables declared by the statement are only in scope until the end of the if.
func pow(x, n, lim float 64) float64 {
    if v:= math.Pow(x, n); v < lim {
        return v
    }
    return lim
}

If and else

  • Variables declared inside an if short statement are also available inside any of the else blocks.
func pow(x, n, lim float 64) float64 {
    if v:= math.Pow(x, n); v < lim {
        return v
    } else {
        fmt.Printf("%g >= %g\n", v, lim)
    }
    // can't use v here, though
    return lim
}

Switch

  • A switch statement is a shorter way to write a sequence of if-else statements. It runs the first case whose value is equal to the condition.
  • Go's switch is like the one in C, C++, Java, JS, and PHP, except that Go only runs the selected case, not all the cases that follow. In effect, the break statement that is needed at the end of each case n those languages is provided automatically in Go.

Switch (2)

func main() {
    fmt.Print("Go runs on")
    switch os := runtime.GOOS; os {
    case "darwin":
        fmt.Println("OS X.")
    case "linux":
        fmt.Println("Linux.")
    default:
        // freebsd, openbsd, plan9, windows...
        fmt.Printf("%s.\n", os)
    }
}

Switch evaluation order

  • Switch cases evaluate cases form top to bottom, stopping when a case succeeds.
switch i {
case 0:
case f(): // does not call f if i==0
}

Switch with no condition

  • Switch without a condition is the same as switch true.
  • This construct can be a clean way to write long if-then-else chains.
t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("Good moorning!")
case t.Hour() < 17:
    fmt.Println("Good afternoon.")
default:
    fmt.Println("Good evening.")
}

Defer

  • A defer statement defers the execution of a function until the surrounding function returns.
  • The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.
func main() {
    defer fmt.Println("world")
    fmt.Println("hello")
}

Stacking defers

  • Deferred function calls are pushed onto a stack.
  • When a function returns, its deferred called are executed in last-in-first-out order.

Pointers

  • Go has pointers. A pointer holds the memory address of a value.
  • The type *T is a pointer to a T value. Its zero value is nil.
  • The & operator generates a pointer to its operand.
  • The * operator denotes the pointer's underlying value. This is known as "dereferencing" or "indirecting".
  • Unlike C, Go has no pointer arithmetic.

Pointers (2)

func main() {
    i, j := 42, 2701

    p := &i         // point to i
    fmt.Println(*p) // read i through the pointer
    *p = 21         // set i through the pointer
    fmt.Println(i)  // see the new value of i

    p = &j          // point to j
    *p = *p / 37    // divide j through the pointer
    fmt.Println(j)  // see the new value of j
}

Structs

  • A struct is a collection of fields.
type Vertex struct {
    X int
    Y int
}

Struct Fields

  • Struct fields are accessed using a dot.
type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v.X)
}

Pointers to structs

  • Struct fields can be accessed through a struct pointer.
  • To access the field X of a struct when we have the struct pointer p we could write (*p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit deference.
func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v.X)
}

Struct Literals

  • A struct literal denotes a newly allocated struct value by listing the values of its fields.
  • You can list just a subset of fields by using the Name: syntax.
  • The special prefix & returns a pointer to th struct value.
var (
    v1 = Vertex{1, 2}   // has type Vertex
    v2 = Vertex{X: 1}   // Y:0 is implicit
    v3 = Vertex{}       // X:0 and Y:0
    p  = &Vertex{1, 2}  // has type *Vertex
}

new, New

  • newは構造体のポインタを作成します.& でもポインタを作成します.
  • newの場合、構造体を初期化することができません.
a := new(Hoge) // a := &Hoge{}
a := &Hoge{"hoge", 10}
a := new(Hoge{"hoge",10}) // error
  • Goにはコンストラクタが存在しません.構造体を作成する関数には慣習的にNewNewXXXという名前が使われます.

Arrays

  • The type [n]T is an array of n values of type T.
  • An arary's length is part of its type, so arrays cannot be resized. This seems limiting, but don't worry; Go provides a convenient way of working with arrays.
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
primes := [6]int{2, 3, 5, 7, 11, 13}
fmt.Println(primes)

Slices

  • An array has a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array. In practice, slices are much more common than arrays.
  • The type []T is a slice with elements of type T.
  • A slice is formed by specifying two indices, a low and high bound, separated by a colon: a[low : high].

Slices are like references to arrays

  • A slice does not store any data, it just describes a section of an underlying array.
  • Changing the elements of a slice modifiers the corresponding elements of its underlying array.
  • Other slices that share the same underlying array will see those changes.

Slice Literals

  • A slice literal is like an array literal without the length.
  • This is an arrayliteral:
[3]bool{true, true, false}
  • And this creates the same array as above, then builds a slice that references it:
[]bool{true, true, false}

Slice defaults

  • When slicing, you may omit the high or low bounds to use their defaults instead.
  • The default is zero for the low bound and the length of the slice for the high bound.
  • These slice expressions are equivalent:
a[0:10] = a[:10] = a[0:] = a[:]

Slice length and capacity

  • A slice has both a length and a capacity.
  • The length of a slice is the number of elements it contains.
  • The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
  • The length and capacity of a slice s can be obtained using the expressions len(s) and cap(s).
  • You can extend a slice's length by re-slicing it, provided it has sufficient capacity.

Nil slices

  • The zero value of a slice is nil.
  • A nil slice has a length and capacity of 0 and has no underlying array.
func main() {
    var s []int
    fmt.Println(s, len(s), cap(s))
    if s == nil {
        fmt.Println("nil!")
    }
}

Creating a slice with make

  • Slices can be created with the built-in make function; this is how you create dynamically-sized arrays.
  • The make function allocates a zeroed array and returns a slice that refers to that array:
a := make([]int, 5)     // len(a) = 5
a := make([]int, 0, 5)  // len(b) = 0, cap(b) = 5
b = b[:cap(b)]  // len(b) = 5, cap(b) = 5
b = b[1:]       // len(b) = 4, cap(b) = 4

Slices of slices

  • Slices can contain any type, including other slices.
// Create a tic-tac-toe board.
board := [][]string{
    []string{"_", "_", "_"},
    []string{"_", "_", "_"},
    []string{"_", "_", "_"},
}
// The players take turns
board[0][0] = "X"
board[2][2] = "O"
board[1][2] = "X"
board[1][0] = "O"
board[0][2] = "X"

Appending to a slice

  • It is common to append new elements to a slice, and so Go provides a built-in append function.
  • It the backing array of s is too small to fit all the given values a bigger array will be allocated. The returned slice will point to the newly allocated array.
// append works on nil slices
s = append(s, 0)
// The slice grows as needed.
s = append(s, 1)
// We can add more than one element at a time.
s = append(s, 2, 3, 4)

Range

  • The range from of the for loop iterates over a slice or map.
  • When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
    for i, v := range pow {
        fmt.Printf("2**%d = %d\n", i, v)
    }
}

Range(2)

  • You can skip the index or value by assigning to _.
for i, _ := range pow
for _, value := range pow
  • If you only want the index, you can omit the second variable.
for i := range pow

Maps

  • A map maps keys to values.
  • The zero value of a map is nil. A nil map has no keys, nor can keys be added.
  • The make function returns a map of the given type, initialized and ready for use.
var m map[string]Vertex
func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{40.68433, -74.39967}
    fmt.Println(m["Bell Labs"])
}

Map literals

  • Map literals are like struct literals, but the keys are required.
type Vertex struct {
    Lat, Long float64
}

var m = map[string]Vertex{
    "Bell Labs": Vertex{40.68433, -74.39967},
    "Google": Vertex{37.42202, -122.08408},
}

Map literals (2)

  • If the top-level type is just a type name, you can omit it from the elements of the literal.
type Vertex struct {
    Lat, Long float64
}

var m = map[string]Vertex{
    "Bell Labs": {40.68433, -74.39967},
    "Google": {37.42202, -122.08408},
}

Mutating Maps

// insert or update an element in map m
m[key] = elem

// retrieve an element
elem = m[key]

// delete an element
delete(m, key)

// Test that a key is present with a two-value assignment
elem, ok = m[key]

Mutating Maps(2)

  • Note: If elem or ok have not yet been declared you could use a short declaration from:
elem, ok := m[key]

Function values

  • Functions are values too. They can be passed around just like other values.
  • Function values may be used as function arguments and return values.
func compute(fn func(float64, float64), float64) float64 {
    return fn(3, 4)
}
func main() {
    hypot := func(x, y float64) float64 {
        return math.Sqrt(x*x + y*y)
    }
    fmt.Println(hypot(5, 12))
    fmt.Println(compute(hypot))
    fmt.Println(compute(math.Pow))
}

Function closures

  • Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.

Function closure(2)

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}
func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(pos(i), neg(-2*i))
    }
}

Variadic parameter

func sum(args ...int) int {
    n := len(args)
    v := args[0]

    sum := 0
    for i, v := range args {
        sum += v // sum += args[i]
    }
    return sum
}

fmt

  • Package fmt implements formatted I/O with functions analogous to C's printf and scanf. The format "verbs" and derived from C's but are simpler.
%v   the value i a default format
     when printing structs, the plus flag (%+v) adds field names
%#v  a Go-syntax representation of the value
%T   a Go-syntax representation of the type of the value
%%   a literal percent sign; consumes no value
%t   the word true or false
%d   base 10
%q   a single-quoted character literal safely escaped with Go syntax
     a double-quoted string safely escaped with Go syntax
%p   base 16 notation, with leading 0x (pointer)

Methods and interfaces


Methods

  • Go does not have classes. However, you can define methods on types.
  • A method is a function with a special receiver argument.
  • The receiver appears in its own argument list between the func keyword and the method name.
func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
    v := Vertex{3, 4}
    fmt.Pritnln(v.Abs())
}

Methods are functions

  • Remember: a method is just a function with a receiver argument.
func Abs(v Vertex) float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
    v := Vertex{3, 4}
    fmt.Pritnln(Abs(v))
}

Methods (2)

  • You can declare a method on non-struct types, too.
  • You can only declare a method with a receiver whose type is defined in the same package as the method.
  • You cannot declare a method with a receiver whose type is defined in another package.

Methods (3)

type MyFloat float64
func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}
func main() {
    f := MyFloat(-math.Sqrt2)
    fmt.Pritnln(f.Abs())
}

Pointer receivers

  • You can declare methods with pointer receivers.
  • This means the receiver type has the literal syntax *T for some type T.
  • Methods with pointer receivers can modify the value to which the receiver points.
func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}
func main() {
    v := Vertex{3, 4}
    v.Scale(10)
    fmt.Println(v.Abs())
}

Methods and pointer indirection

  • Comparing the previous two programs, you might notice that functions with a pointer argument must take a pointer:
func ScaleFunc(v *Vertex, f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}
var v Vertex
ScaleFunc(v, 5)     // Compile error!
ScaleFunc(&v, 5)    // OK

Methods and pointer indirection (2)

  • While methods with pointer receivers take either a value or a pointer as the receiver when they are called:
func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}
var v Vertex
v.Scale(5)  // OK
p := &v
p.Scale(10) // OK

Choosing a value or pointer receiver

  • There are two reasons to use a pointer receiver.
  • The first is so that the method can modify the value that its receiver points to.
  • The second is to avoid copying the value on each method call. This can be more efficient if the receiver is a large struct, for example.
  • In general, all methods on a given type should have either value or pointer receivers, but not a mixture of both.

Interfaces

  • An interface type is defined as a set of method signatures.
  • A value of interface type can hold any value that implements those methods.
type Abser interface {
    Abs() float64
}

Interfaces are implemented implicitly

  • A type implements an interface by implementing its methods. There is no explicit declaration of intent, no "implements" keyword.
  • Implicit interfaces decouple the definition of an interface from its implkementation, which could then appear in any package without prearrangement.

Interfaces are implemented implicitly

type I interface {
    M()
}

type T struct {
    S string
}

// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M() {
    fmt.Println(t.S)
}

Interface values

  • Under the hood, interface values can be thought of as a tuple of a value and a concrete type:
(value, type)
  • An interface value holds a value of a specific underlying concrete type.
  • Calling a method on an interface value executes the method of th same name on its underlying type.

Interface values with nil underlying values

  • If the concrete value inside the interface itself is nil, the method will be called with a nil receiver.
  • In some languages this would trigger a null pointer exception, but in Go it is common to write methods that gracefully handle being called with a nil receiver.
  • Note that an interface value that holds a nil concrete value is itself non-nil.

Nil interface values

  • A nil interface value holds neither value nor concreate type.
  • Calling a method on a nil interface is a run-time error because there is no type inside the interface tuple to indicate which concrete method to call.

The empty interface

  • The interface type that specifies zero methods is known as the empty interface:
interface{}
  • An empty interface may hold values of any type. (Every type implements at least zero methods.)
  • Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.

Type assertions

  • A type assertion provides access to an interface value's underlying concreate value.
t := i.(T)
  • This statement asserts that the interface value i holds the concrete type T and assigns the underlying T value to the variable t. If i does not hold a T, the statement will trigger a panic.

Type assetions (2)

  • To test whether an interface value holds a specific type, a type assertion can return two values: the underlying value and a boolean value that reports whether the assertion.
t, ok := i.(T)
  • If i holds a T, then t will be the underlying value and ok will be true.
  • If not, ok will be false and t will be the zero value of type T, and no panic occurs.

Type switches

  • A type switch is a construct that permits several type assertions in series.
  • A type switch is like a regular switch statement, but the cases in a type switch specify types (not values), and those values are compared against the type of the value held by the given interface value.
switch v := i.(type) {
case T:
    // here v has type T
case S:
    // here v has type S
default:
    // no match; here v has the same type as i
}

Stringers

  • One of the most ubiquistous interfaces is Stringers defined by the fmt package.
type Stringer interface {
    String() string
}
  • A Stringer is a type that can describe itself as a string. The fmt package (and many others) look for this interface to print values.

Errors

  • Go programs express error state with error values.
  • The error type is a built-in interface similar to fmt.Stringer.
type error interface {
    Error() string
}

Errors (2)

  • Functions often return an error value, and calling code should handle errors by testing whether the error equals nil.
i, err := strconv.Atoi("42")
if err != nil {
    fmt.Print("Couldn't convert number: %v\n", err)
    return
}
fmt.Println("Converted integer:", i)
  • A nil error denotes success; a non-nil error denotes failure.

Generics


Type parameters

  • Go functions can be written to work on multiple types using type parameters. The type parameters of a function appear between brackets, before the function's argumetns.
func Index[T comparable](s []T, x T) int
  • This declaration means that s is a slice of any type T that fulfills the built-in constraint comparable. x is also a value of type same type.
  • comparable is a useful constraint that makes it possible to use the == and != operators on values of the type.

Generic types

  • In addition to generic functions, Go also supports generic types. A type can be parameterized with a type parameter, which could be useful for implementing generic data structures.
// List represents a singly-linked list that holds
// values of any type.
type List[T any] struct {
    next *List[T]
    val T
}

Concurrency


Goroutines

  • A goroutines is a lightweight thread managed by the Go runtime.
go f(x, y, z)
  • The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in the new goroutine.
  • Goroutines run in the same address space, so access to shared memory must be synchronized. The sync package provides useful primitives, although you won't need them much in Go as there are other primitives.

Channels

  • Channels are a typed conduit through which you can send and receive values with the channel operator, <-.
ch <- v     // Send v to channel ch.
v := <-ch   // Receive from ch, and assign value to v.
  • Like maps and slices, channels must be created befeore use:
ch := make(chan int)
  • By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

Buffered Channels

  • Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channels:
ch := make(chan int, 100)
  • Sends to buffered channel block only when the buffer is full. Receives block when the buffer is empty.

Range and Close

  • A sender can close a channel to indicate that no more values will be sent. Receivers can that whether a channel has been closed by assigning a second parameter to the receive expression:
v, ok := <-ch
  • ok is false if there are no more values to receive and the channel is closed.
  • The loop for i := range c receives values from the channel repeatedly until it is closed.
  • Only the sender should close a channel, never the receiver.

Select

  • The select statement let's a goroutine wait on multiple communication operations.
  • A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
select {
case c <- x:
    x, y = y, x+y
case <- quit:
    fmt.Println("quit")
    return
}

Default Selection

  • The default case in a select is run if no other case is ready.
  • Use a default case to try a send or receive without blocking:
select {
case i := <-c:
    // use i
default:
    // receiving from c would block
}

sync.Mutex

  • Go's standard library provides mutual exclusion with sync.Mutex andits two methods: Lock, Unlock:
// SafeCounter is safe to use concurrently.
type SafeCounter struct {
    mu sync.Mutex
    v  map[string] int
}
// Inc increments the counter for the given key.
func (c *SafeCounter) Inc(key string) {
    c.mu.Lock()
    // Lock so only one goroutine at a time can access the map c.v.
    c.v[key]++
    c.mu.Unlock()
}

Testing


テストファイルの作成

  • テストファイルはテストしたファイル名に _test を付けた名前で作成する.
  • テスト関数は TestXXX とCamel方式で書く.
  • テストの実行はコマンドラインで test を指定.
# テスト実行
go test <path> [-v]

# 特定のテストだけ実行したい場合
go test <path> [-v] -run <pattern>

# テストのキャッシュを削除したい場合
go test <path> [-v] -count=1

失敗を示す関数

  • T.Error, T.ErrorfT.Fatal, T.Fatalf があります.
  • T.Fatal[f] を実行すると以降のテストは実行されません.
  • T.Error[f] は以降の処理を継続します.
  • よって、初期化など処理が失敗するとそれ以降の処理が未定になる場合 T.Fatal[f] を使い、それ以外は T.Error[f] を使います.

ベンチマーク

  • テスト関数の引数に *testing.B を指定します.
  • テストコマンドで -bench を指定します.
go test <path> -bench[=pattern]
  • 特定の処理だけベンチマークを取りたい場合、StartTimer(), StopTime(), ResetTimer() を使います.
[config]
skip_core_tasks = true
[tasks.default]
alias = "build"
[tasks.build]
description = "Build css"
category = "Common"
script_runner = "pwsh"
script_extension = "ps1"
script = '''
$header = @"
/* @theme {THEME_NAME} */
@import "default";
"@
function GetPreviewPath([string]$Path) {
$parentDir = Split-Path $Path -Parent
$baseName = Split-Path $Path -LeafBase
$extension = Split-Path -Extension $Path
return Join-Path $parentDir "${baseName}-preview${extension}"
}
Get-ChildItem marp-*.less | ForEach-Object {
$themeName = $_.BaseName.Replace("marp-", "");
$outName = $_.FullName.Replace(".less", ".css");
# light theme
Write-Output $header.Replace("{THEME_NAME}", $themeName) | Out-File $outName -Encoding utf8
lessc $_.FullName | Out-File $outName -Append -Encoding utf8
# dark theme
$darkThemeName = $themeName + "-dark";
$darkOutName = $outName.Replace(".css", "-dark.css");
Write-Output $header.Replace("{THEME_NAME}", $darkThemeName) | Out-File $darkOutName -Encoding utf8
$content = Get-Content $_.FullName -Raw
$content = $content.Replace('@import "_light";', '@import "_dark";');
$content = $content.Replace("@dark: false;", "@dark: true;");
$content | lessc - | Out-File $darkOutName -Append -Encoding utf8
}
'''
[tasks.watch]
command = "watchexec"
args = [
"-e", "less",
"-p",
"--delay-run=1sec",
"--clear=reset",
"makers", "build"
]
[tasks.test]
description = "lists all known steps"
category = "Common"
command = "makers"
args = [
"${@}",
"--list-all-steps"
]
/* stylelint-disable no-descending-specificity -- https://github.com/stylelint/stylelint/issues/5065 */
/*!
* Marp default theme.
*
* @theme default
* @author Yuki Hattori
*
* @auto-scaling true
* @size 16:9 1280px 720px
* @size 4:3 960px 720px
*/
@import '~github-markdown-css';
h1 {
border-bottom: none;
color: var(--h1-color);
font-size: 1.6em;
}
h2 {
border-bottom: none;
font-size: 1.3em;
}
h3 {
font-size: 1.1em;
}
h4 {
font-size: 1.05em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 0.9em;
}
h1,
h2,
h3,
h4,
h5,
h6 {
strong {
font-weight: inherit;
color: var(--heading-strong-color);
}
&::part(auto-scaling) {
max-height: 563px; // Slide height - padding * 2
}
}
hr {
height: 0;
padding-top: 0.25em;
}
img {
background-color: transparent;
}
pre {
/* stylelint-disable-next-line custom-property-pattern */
border: 1px solid var(--borderColor-default);
line-height: 1.15;
overflow: visible;
&::part(auto-scaling) {
// Slide height - padding * 2 - code's padding * 3 - code's border * 2
max-height: 529px;
}
// GitHub's prettylights -> Highlight.js
/* stylelint-disable selector-class-pattern */
:where(.hljs) {
color: var(--color-prettylights-syntax-storage-modifier-import);
}
:where(.hljs-doctag),
:where(.hljs-keyword),
:where(.hljs-meta .hljs-keyword),
:where(.hljs-template-tag),
:where(.hljs-template-variable),
:where(.hljs-type),
:where(.hljs-variable.language_) {
color: var(--color-prettylights-syntax-keyword);
}
:where(.hljs-title),
:where(.hljs-title.class_),
:where(.hljs-title.class_.inherited__),
:where(.hljs-title.function_) {
color: var(--color-prettylights-syntax-entity);
}
:where(.hljs-attr),
:where(.hljs-attribute),
:where(.hljs-literal),
:where(.hljs-meta),
:where(.hljs-number),
:where(.hljs-operator),
:where(.hljs-selector-attr),
:where(.hljs-selector-class),
:where(.hljs-selector-id),
:where(.hljs-variable) {
color: var(--color-prettylights-syntax-constant);
}
:where(.hljs-string),
:where(.hljs-meta .hljs-string),
:where(.hljs-regexp) {
color: var(--color-prettylights-syntax-string);
}
:where(.hljs-built_in),
:where(.hljs-symbol) {
color: var(--color-prettylights-syntax-variable);
}
:where(.hljs-code),
:where(.hljs-comment),
:where(.hljs-formula) {
color: var(--color-prettylights-syntax-comment);
}
:where(.hljs-name),
:where(.hljs-quote),
:where(.hljs-selector-pseudo),
:where(.hljs-selector-tag) {
color: var(--color-prettylights-syntax-entity-tag);
}
:where(.hljs-subst) {
color: var(--color-prettylights-syntax-storage-modifier-import);
}
:where(.hljs-section) {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-heading);
}
:where(.hljs-bullet) {
color: var(--color-prettylights-syntax-markup-list);
}
:where(.hljs-emphasis) {
font-style: italic;
color: var(--color-prettylights-syntax-markup-italic);
}
:where(.hljs-strong) {
font-weight: bold;
color: var(--color-prettylights-syntax-markup-bold);
}
:where(.hljs-addition) {
color: var(--color-prettylights-syntax-markup-inserted-text);
background-color: var(--color-prettylights-syntax-markup-inserted-bg);
}
:where(.hljs-deletion) {
color: var(--color-prettylights-syntax-markup-deleted-text);
background-color: var(--color-prettylights-syntax-markup-deleted-bg);
}
/* stylelint-enable selector-class-pattern */
}
header,
footer {
margin: 0;
position: absolute;
left: 30px;
color: var(--header-footer-color);
font-size: 18px;
}
header {
top: 21px;
}
footer {
bottom: 21px;
}
section {
/* stylelint-disable-next-line scss/at-extend-no-missing-placeholder */
@extend .markdown-body;
--h1-color: #246;
--header-footer-color: #{rgba(#666, 0.75)};
--heading-strong-color: #48c;
--paginate-color: #777;
display: block;
place-content: safe center center;
font-size: 29px;
height: 720px;
padding: 78.5px;
width: 1280px;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
&:where(.invert) {
--h1-color: #cee7ff;
--header-footer-color: #{rgba(#999, 0.75)};
--heading-strong-color: #7bf;
--paginate-color: #999;
}
> *:last-child,
&[data-footer] > :nth-last-child(2) {
margin-bottom: 0;
}
> *:first-child,
> header:first-child + * {
margin-top: 0;
}
&::after {
position: absolute;
padding: 0;
right: 30px;
bottom: 21px;
font-size: 24px;
color: var(--paginate-color);
}
&[data-color] {
h1,
h2,
h3,
h4,
h5,
h6 {
color: currentcolor;
}
}
}
@use 'sass:color';
/*!
* Marp / Marpit Gaia theme.
*
* @theme gaia
* @author Yuki Hattori
*
* @auto-scaling true
* @size 16:9 1280px 720px
* @size 4:3 960px 720px
*/
$color-light: #fff8e1;
$color-dark: #455a64;
$color-primary: #0288d1;
$color-secondary: #81d4fa;
@import 'https://fonts.bunny.net/css?family=Lato:400,900|Roboto+Mono:400,700&display=swap';
@import '~highlight.js/styles/sunburst';
@mixin color-scheme($bg, $text, $highlight) {
--color-background: #{$bg};
--color-background-stripe: #{rgba($text, 0.1)};
--color-foreground: #{$text};
--color-dimmed: #{color.mix($text, $bg, 80%)};
--color-highlight: #{$highlight};
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0.5em 0 0;
strong {
font-weight: inherit;
}
&::part(auto-scaling) {
max-height: 580px; // Slide height - padding * 2
}
}
h1 {
font-size: 1.8em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.3em;
}
h4 {
font-size: 1.1em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 0.9em;
}
p,
blockquote {
margin: 1em 0 0;
}
ul,
ol {
> li {
margin: 0.3em 0 0;
> p {
margin: 0.6em 0 0;
}
}
}
code {
display: inline-block;
font-family: 'Roboto Mono', monospace;
font-size: 0.8em;
letter-spacing: 0;
margin: -0.1em 0.15em;
padding: 0.1em 0.2em;
vertical-align: baseline;
}
pre {
display: block;
margin: 1em 0 0;
overflow: visible;
code {
box-sizing: border-box;
margin: 0;
min-width: 100%;
padding: 0.5em;
font-size: 0.7em;
}
&::part(auto-scaling) {
max-height: calc(580px - 1em);
}
}
blockquote {
margin: 1em 0 0;
padding: 0 1em;
position: relative;
&::after,
&::before {
content: '“';
display: block;
font-family: 'Times New Roman', serif;
font-weight: bold;
position: absolute;
}
&::before {
top: 0;
left: 0;
}
&::after {
right: 0;
bottom: 0;
transform: rotate(180deg);
}
> *:first-child {
margin-top: 0;
}
}
mark {
background: transparent;
}
table {
border-spacing: 0;
border-collapse: collapse;
margin: 1em 0 0;
th,
td {
padding: 0.2em 0.4em;
border-width: 1px;
border-style: solid;
}
}
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: var(--color-background);
background-image: linear-gradient(
135deg,
rgba(#888, 0),
rgba(#888, 0.02) 50%,
rgba(#fff, 0) 50%,
rgba(#fff, 0.05)
);
color: var(--color-foreground);
font-size: 35px;
font-family: Lato, 'Avenir Next', Avenir, 'Trebuchet MS', 'Segoe UI',
sans-serif;
height: 720px;
line-height: 1.35;
letter-spacing: 1.25px;
padding: 70px;
width: 1280px;
word-wrap: break-word;
@include color-scheme($color-light, $color-dark, $color-primary);
&::after {
right: 0;
bottom: 0;
font-size: 80%;
}
a,
mark {
color: var(--color-highlight);
}
code {
background: var(--color-dimmed);
color: var(--color-background);
}
h1,
h2,
h3,
h4,
h5,
h6 {
strong {
color: var(--color-highlight);
}
}
pre {
background: var(--color-foreground);
}
pre > code {
background: transparent;
}
header,
footer,
section::after,
blockquote::before,
blockquote::after {
color: var(--color-dimmed);
}
table {
th,
td {
border-color: var(--color-foreground);
}
thead th {
background: var(--color-foreground);
color: var(--color-background);
}
tbody > tr:nth-child(odd) {
td,
th {
background: var(--color-background-stripe, transparent);
}
}
}
> *:first-child,
> header:first-child + * {
margin-top: 0;
}
&:where(.invert) {
@include color-scheme($color-dark, $color-light, $color-secondary);
}
&:where(.gaia) {
@include color-scheme($color-primary, $color-light, $color-secondary);
}
&:where(.lead) {
place-content: safe center center;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
h1,
h2,
h3,
h4,
h5,
h6 {
text-align: center;
}
/* stylelint-disable-next-line no-descending-specificity */
p {
text-align: center;
}
blockquote {
> h1,
> h2,
> h3,
> h4,
> h5,
> h6,
> p {
text-align: left;
}
}
ul,
ol {
> li > p {
text-align: left;
}
}
table {
margin-left: auto;
margin-right: auto;
}
}
}
/* @theme pixy-dark */
@import "default";
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: #242424;
color: #eee;
place-content: unset;
}
section > *:first-child,
section > header:first-child + * {
margin-top: 0;
}
section * {
font-family: Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea", "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
}
section h1 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
font-size: 2.2em;
color: #ffcc00;
}
section h2 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #ffcc00;
}
section h3 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #0cf;
}
section p {
font-size: 1.5em;
line-height: 1.6em;
}
section table {
border: 3px solid #505050;
}
section li {
font-size: 1.2em;
}
section ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
section ul ul li {
font-size: 1em;
}
section ul ul ul li,
section ul ul ul ul li,
section ul ul ul ul ul li {
font-size: 0.85em;
}
section th {
color: #444;
background-color: #eee;
}
section td {
color: #272822;
background-color: #eee;
}
section p strong,
section ul li strong {
color: #0cf;
}
section p em strong,
section ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: #b92a2c;
color: #ebedf0;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
section.text-sm p {
font-size: 1.4em;
line-height: 1.5em;
}
section.text-xs p {
font-size: 1.3em;
line-height: 1.4em;
}
section.full {
padding: 30px;
margin: 0px;
}
section.full h1 {
font-size: 1.5em;
}
section.decorate > h1 {
border-bottom: 2px solid #b38f00;
padding-bottom: 10px;
margin-bottom: 40px;
}
section.code > pre {
font-size: 0.9em;
}
section.highlight > h1 {
color: #b92a2c;
margin: 0 0 0.5em 0;
}
section.advanced > h1 {
color: #00a400;
}
section.lead {
place-content: safe center center;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
/* stylelint-disable-next-line no-descending-specificity */
}
section.lead h1,
section.lead h2,
section.lead h3,
section.lead h4,
section.lead h5,
section.lead h6 {
font-size: 3em;
text-align: center;
}
section.lead p {
text-align: center;
}
section.lead blockquote > h1,
section.lead blockquote > h2,
section.lead blockquote > h3,
section.lead blockquote > h4,
section.lead blockquote > h5,
section.lead blockquote > h6,
section.lead blockquote > p {
text-align: left;
}
section.lead ul > li > p,
section.lead ol > li > p {
text-align: left;
}
section.lead table {
margin-left: auto;
margin-right: auto;
}
section.rowhdr table tr > *:first-child {
color: #0cf;
background-color: #444;
}
section.center img {
margin: auto;
display: block;
}
section :is(pre, marp-pre) * {
font-family: "Sarasa Fixed J", "Iosevka Fixed", "Inconsolata", "Fira Mono", Consolas, "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", monospace;
font-size: 0.9em;
}
section :is(pre, marp-pre) {
line-height: 1.35em;
}
/* @theme pixy-prog-dark */
@import "default";
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: #242424;
color: #eee;
place-content: unset;
padding: 0;
margin: 0;
}
section.lead,
section.topic {
place-content: safe center center;
/* Definitions for classic behavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
text-align: center;
}
section.lead h1,
section.topic h1,
section.lead h2,
section.topic h2,
section.lead h3,
section.topic h3,
section.lead h4,
section.topic h4,
section.lead h5,
section.topic h5,
section.lead h6,
section.topic h6 {
font-size: 2.6em;
}
section p,
section ul,
section ol {
margin: 20px 40px;
}
section > *:first-child,
section > header:first-child + * {
margin-top: 0;
}
section * {
font-family: Gudea, "UD デジタル 教科書体 NK-R", Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
}
section h1 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
font-size: 2em;
color: #242424;
background-color: #ffcc00;
padding: 16px 80px;
}
section h2 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #ffcc00;
}
section h3 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #0cf;
}
section.lead h1 {
color: #ffcc00;
background-color: #242424;
padding: 0;
}
section.lead.text-sm h1 {
font-size: 1.8em;
}
section.lead.text-xs h1 {
font-size: 1.6em;
}
section.topic h1 {
color: #ffcc00;
background-color: #242424;
border-bottom: 5px solid #e6b800;
display: inline-block;
padding: 0;
}
section p {
font-size: 1.4em;
line-height: 1.6em;
}
section.text-xs p {
font-size: 1.2em;
line-height: 1.4em;
}
section.text-sm p {
font-size: 1.3em;
line-height: 1.5em;
}
section table {
border: 3px solid #505050;
}
section li {
font-size: 1.12em;
}
section ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
section ul ul li {
font-size: 1em;
}
section ul ul ul li,
section ul ul ul ul li,
section ul ul ul ul ul li {
font-size: 0.84em;
}
section th {
color: #444;
background-color: #eee;
}
section td {
color: #272822;
background-color: #eee;
}
section p strong,
section ul li strong {
color: #ff5050;
}
section p em strong,
section ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: #b92a2c;
color: #ebedf0;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
section p > code,
section ul code,
section ol code {
font-family: "Iosevka Fixed", "Inconsolata", "Fira Mono", "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
font-size: 0.84rem;
padding: 0.1em 0.3em;
background-color: #376092;
}
section :is(pre, marp-pre, table) {
margin: 30px 80px;
}
section :is(p, ul, li) + :is(pre, marp-pre, table) {
margin: 10px 80px;
}
section.table > :is(pre, marp-pre, img, table),
section.figure > :is(pre, marp-pre, img, table),
section.list > :is(pre, marp-pre, img, table) {
margin-top: 40px;
}
section.table > :is(img, table),
section.figure > :is(img, table),
section.list > :is(img, table) {
margin-inline: auto;
}
section :is(pre, marp-pre) {
line-height: 1rem;
border: 2px dashed #b38f00;
}
section :is(pre, marp-pre) span,
section :is(pre, marp-pre) code {
font-family: "Iosevka Fixed", "Inconsolata", "Fira Mono", "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo !important;
font-size: 0.7rem !important;
}
section :is(pre, marp-pre) span.hljs-title {
color: #A6E22E;
}
section :is(pre, marp-pre) span.hljs-string {
color: #FFEE99;
}
section :is(pre, marp-pre) {
border: 2px dashed #b38f00;
background-color: #242424;
color: #eee;
}
section.rowhdr table tr > *:first-child {
color: #0cf;
background-color: #444;
}
/* @theme pixy-prog */
@import "default";
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: #eee;
color: #282c2f;
place-content: unset;
padding: 0;
margin: 0;
}
section.lead,
section.topic {
place-content: safe center center;
/* Definitions for classic behavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
text-align: center;
}
section.lead h1,
section.topic h1,
section.lead h2,
section.topic h2,
section.lead h3,
section.topic h3,
section.lead h4,
section.topic h4,
section.lead h5,
section.topic h5,
section.lead h6,
section.topic h6 {
font-size: 2.6em;
}
section p,
section ul,
section ol {
margin: 20px 40px;
}
section > *:first-child,
section > header:first-child + * {
margin-top: 0;
}
section * {
font-family: Gudea, "UD デジタル 教科書体 NK-R", Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
}
section h1 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
font-size: 2em;
color: #eee;
background-color: #3578f6;
padding: 16px 80px;
}
section h2 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #3578f6;
}
section h3 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #d21a4e;
}
section.lead h1 {
color: #3578f6;
background-color: #eee;
padding: 0;
}
section.lead.text-sm h1 {
font-size: 1.8em;
}
section.lead.text-xs h1 {
font-size: 1.6em;
}
section.topic h1 {
color: #3578f6;
background-color: #eee;
border-bottom: 5px solid #1865f5;
display: inline-block;
padding: 0;
}
section p {
font-size: 1.4em;
line-height: 1.6em;
}
section.text-xs p {
font-size: 1.2em;
line-height: 1.4em;
}
section.text-sm p {
font-size: 1.3em;
line-height: 1.5em;
}
section table {
border: 3px solid #505050;
}
section li {
font-size: 1.12em;
}
section ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
section ul ul li {
font-size: 1em;
}
section ul ul ul li,
section ul ul ul ul li,
section ul ul ul ul ul li {
font-size: 0.84em;
}
section th {
color: #444;
background-color: #eee;
}
section td {
color: #444;
background-color: #eee;
}
section p strong,
section ul li strong {
color: #ff5050;
}
section p em strong,
section ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: #b92a2c;
color: #ebedf0;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
section p > code,
section ul code,
section ol code {
font-family: "Iosevka Fixed", "Inconsolata", "Fira Mono", "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
font-size: 0.84rem;
padding: 0.1em 0.3em;
}
section :is(pre, marp-pre, table) {
margin: 30px 80px;
}
section :is(p, ul, li) + :is(pre, marp-pre, table) {
margin: 10px 80px;
}
section.table > :is(pre, marp-pre, img, table),
section.figure > :is(pre, marp-pre, img, table),
section.list > :is(pre, marp-pre, img, table) {
margin-top: 40px;
}
section.table > :is(img, table),
section.figure > :is(img, table),
section.list > :is(img, table) {
margin-inline: auto;
}
section :is(pre, marp-pre) {
line-height: 1rem;
border: 2px dashed #094bc8;
}
section :is(pre, marp-pre) span,
section :is(pre, marp-pre) code {
font-family: "Iosevka Fixed", "Inconsolata", "Fira Mono", "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo !important;
font-size: 0.7rem !important;
}
section.rowhdr table tr > *:first-child {
color: #eee;
background-color: #444;
}
@import "_slim";
@import "_light";
@dark: false;
& when (@dark = true) {
@color-background: #1e2431; // Indigo
}
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
.rounded(@radius) {
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
}
section {
background-color: @color-background;
color: @color-foreground;
place-content: unset;
padding: 0;
margin: 0;
&.lead,
&.topic {
place-content: safe center center;
/* Definitions for classic behavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
text-align: center;
h1, h2, h3, h4, h5, h6 {
font-size: @font-size-lead;
}
}
p, ul, ol {
margin: 20px 40px;
}
// height: 720px;
// line-height: 1.35;
// letter-spacing: 1.25px;
// padding: 70px;
// width: 1280px;
// word-wrap: break-word;
> *:first-child,
> header:first-child + * {
margin-top: 0;
}
* {
font-family: @font-family-base;
}
h1 {
font-family: @font-family-serif;
font-size: @font-size-head;
color: @color-background;
background-color: @color-heading-1;
padding: 16px 80px;
}
h2 {
font-family: @font-family-serif;
color: @color-heading-2;
}
h3 {
font-family: @font-family-serif;
color: @color-heading-3;
}
&.lead {
h1 {
color: @color-heading-1;
background-color: @color-background;
padding: 0;
}
}
&.lead {
&.text-sm {
h1 { font-size: @font-size-head-sm; }
}
&.text-xs {
h1 { font-size: @font-size-head-xs; }
}
}
&.topic {
h1 {
color: @color-heading-1;
background-color: @color-background;
border-bottom: 5px solid @color-primary-dark;
display: inline-block;
// .rounded(10px);
padding: 0;
}
}
p {
font-size: @font-size-base;
line-height: @line-height;
}
&.text-xs {
p {
font-size: @font-size-xs;
line-height: @line-height-xs;
}
}
&.text-sm {
p {
font-size: @font-size-sm;
line-height: @line-height-sm;
}
}
table {
border: 3px solid rgb(80, 80, 80);
}
// th, td,
li {
font-size: @font-size-base * 0.8;
}
ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
ul ul li {
font-size: 1em;
}
ul ul ul li,
ul ul ul ul li,
ul ul ul ul ul li {
font-size: @font-size-base * 0.6;
}
th {
color: @color-table-head-background;
background-color: @color-table-head-foreground;
}
td {
color: @color-table-background;
background-color: @color-table-foreground;
}
p strong,
ul li strong {
color: #ff5050;
}
p em strong,
ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: @color-highlight;
color: @color-secondary;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
p > code,
ul code,
ol code {
font-family: @font-family-mono;
font-size: @font-size-code * 1.2;
padding: .1em .3em;
& when (@dark = true) {
background-color: #376092;
}
}
:is(pre, marp-pre, table) {
margin: 30px 80px;
}
:is(p, ul, li) + :is(pre, marp-pre, table) {
margin: 10px 80px;
}
&.table,
&.figure,
&.list {
& > :is(pre, marp-pre, img, table) {
margin-top: 40px;
}
& > :is(img, table) {
margin-inline: auto;
}
}
:is(pre, marp-pre) {
line-height: 1rem;
border: 2px dashed @color-primary-darkest;
}
:is(pre, marp-pre) span,
:is(pre, marp-pre) code {
font-family: @font-family-mono !important;
font-size: @font-size-code !important;
}
:is(pre, marp-pre) span when (@dark = true) {
// &.hljs-keyword {
// }
&.hljs-title {
color: #A6E22E;
}
&.hljs-string {
color: #FFEE99;
}
}
:is(pre, marp-pre) when (@dark = true) {
border: 2px dashed @color-primary-darkest;
background-color: #242424;
color: @color-foreground;
}
&.rowhdr {
table {
tr > *:first-child {
color: @color-table-head-row-foreground;
background-color: @color-table-head-row-background;
}
}
}
}
/* @theme pixy */
@import "default";
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: #eee;
color: #282c2f;
place-content: unset;
}
section > *:first-child,
section > header:first-child + * {
margin-top: 0;
}
section * {
font-family: Roboto, "UDDK-NKR+Gudea", "BIZUDP+Gudea", "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP", "Hiragino Kaku Gothic ProN", Meiryo;
}
section h1 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
font-size: 2.2em;
color: #3578f6;
}
section h2 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #3578f6;
}
section h3 {
font-family: "Merriweather", "PT Serif", "Times New Roman", Times, "UD デジタル 教科書体 NK-R", "BIZ UDPゴシック", "Noto Sans JP";
color: #d21a4e;
}
section p {
font-size: 1.5em;
line-height: 1.6em;
}
section table {
border: 3px solid #505050;
}
section li {
font-size: 1.2em;
}
section ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
section ul ul li {
font-size: 1em;
}
section ul ul ul li,
section ul ul ul ul li,
section ul ul ul ul ul li {
font-size: 0.85em;
}
section th {
color: #444;
background-color: #eee;
}
section td {
color: #444;
background-color: #eee;
}
section p strong,
section ul li strong {
color: #0cf;
}
section p em strong,
section ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: #b92a2c;
color: #ebedf0;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
section.text-sm p {
font-size: 1.4em;
line-height: 1.5em;
}
section.text-xs p {
font-size: 1.3em;
line-height: 1.4em;
}
section.full {
padding: 30px;
margin: 0px;
}
section.full h1 {
font-size: 1.5em;
}
section.decorate > h1 {
border-bottom: 2px solid #094bc8;
padding-bottom: 10px;
margin-bottom: 40px;
}
section.code > pre {
font-size: 0.9em;
}
section.highlight > h1 {
color: #b92a2c;
margin: 0 0 0.5em 0;
}
section.advanced > h1 {
color: #00a400;
}
section.lead {
place-content: safe center center;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
/* stylelint-disable-next-line no-descending-specificity */
}
section.lead h1,
section.lead h2,
section.lead h3,
section.lead h4,
section.lead h5,
section.lead h6 {
font-size: 3em;
text-align: center;
}
section.lead p {
text-align: center;
}
section.lead blockquote > h1,
section.lead blockquote > h2,
section.lead blockquote > h3,
section.lead blockquote > h4,
section.lead blockquote > h5,
section.lead blockquote > h6,
section.lead blockquote > p {
text-align: left;
}
section.lead ul > li > p,
section.lead ol > li > p {
text-align: left;
}
section.lead table {
margin-left: auto;
margin-right: auto;
}
section.rowhdr table tr > *:first-child {
color: #eee;
background-color: #444;
}
section.center img {
margin: auto;
display: block;
}
section :is(pre, marp-pre) * {
font-family: "Sarasa Fixed J", "Iosevka Fixed", "Inconsolata", "Fira Mono", Consolas, "UD デジタル 教科書体 NK-R", "Noto Sans JP", "Hiragino Kaku Gothic ProN", monospace;
font-size: 0.9em;
}
section :is(pre, marp-pre) {
line-height: 1.35em;
}
@import "_base";
@import "_light";
@dark: false;
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section {
background-color: @color-background;
color: @color-foreground;
place-content: unset;
// height: 720px;
// line-height: 1.35;
// letter-spacing: 1.25px;
// padding: 70px;
// width: 1280px;
// word-wrap: break-word;
> *:first-child,
> header:first-child + * {
margin-top: 0;
}
* {
font-family: @font-family-base;
}
h1 {
font-family: @font-family-serif;
font-size: @font-size-head;
color: @color-heading-1;
}
h2 {
font-family: @font-family-serif;
color: @color-heading-2;
}
h3 {
font-family: @font-family-serif;
color: @color-heading-3;
}
p {
font-size: @font-size-base;
line-height: @line-height-base;
}
table {
border: 3px solid rgb(80, 80, 80);
}
// th, td,
li {
font-size: @font-size-list-1;
}
ul ul {
margin-top: 10px;
margin-bottom: 10px;
}
ul ul li {
font-size: 1em;
}
ul ul ul li,
ul ul ul ul li,
ul ul ul ul ul li {
font-size: @font-size-list-2;
}
th {
color: @color-table-head-background;
background-color: @color-table-head-foreground;
}
td {
color: @color-table-background;
background-color: @color-table-foreground;
}
p strong,
ul li strong {
color: @color-info;
}
p em strong,
ul li em strong {
position: relative;
margin: 0 0 1.5em;
padding: 0.2em;
background: @color-highlight;
color: @color-secondary;
font-size: 1.143em;
font-weight: bold;
font-style: normal;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
&.text-sm {
p {
font-size: @font-size-sm;
line-height: @line-height-sm;
}
}
&.text-xs {
p {
font-size: @font-size-xs;
line-height: @line-height-xs;
}
}
&.full {
h1 {
font-size: @font-size-base;
}
padding: 30px;
margin: 0px;
}
&.decorate > h1 {
border-bottom: 2px solid @color-primary-darkest;
padding-bottom: 10px;
margin-bottom: 40px;
}
&.code > pre {
font-size: @font-size-code;
}
&.highlight > h1 {
color: @color-highlight;
margin: 0 0 0.5em 0;
// position: relative;
// margin: 0 0 1.5em;
// padding: 0.1em 0.4em;
// background: #B92A2C;
// color: #fff;
// border-radius: 5px;
// -webkit-border-radius: 5px;
// -moz-border-radius: 5px;
// display: inline;
}
&.advanced > h1 {
color: @color-success;
// position: relative;
// margin: 0 0 1.5em;
// padding: 0.2em 0.5em;
// background: #008000;
// color: #fff;
// border-radius: 5px;
// -webkit-border-radius: 5px;
// -moz-border-radius: 5px;
// display: inline;
}
&.lead {
place-content: safe center center;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section.lead { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: @font-size-lead;
text-align: center;
}
/* stylelint-disable-next-line no-descending-specificity */
p {
text-align: center;
}
blockquote {
> h1,
> h2,
> h3,
> h4,
> h5,
> h6,
> p {
text-align: left;
}
}
ul,
ol {
> li > p {
text-align: left;
}
}
table {
margin-left: auto;
margin-right: auto;
}
}
&.rowhdr {
table {
tr > *:first-child {
color: @color-table-head-row-foreground;
background-color: @color-table-head-row-background;
}
}
}
&.center img {
margin: auto;
display: block;
}
// &.katex-display {
// font-size: 0.8em;
// }
:is(pre, marp-pre) * {
font-family: @font-family-mono;
font-size: 0.9em;
}
:is(pre, marp-pre) {
line-height: 1.35em;
}
}
@use 'sass:color';
/*!
* Marp / Marpit Uncover theme
*
* @theme uncover
* @author Yuki Hattori
*
* @auto-scaling true
* @size 16:9 1280px 720px
* @size 4:3 960px 720px
*/
@mixin color-scheme($bg: #fdfcff, $text: #202228, $highlight: #009dd5) {
--color-background: #{$bg};
--color-background-code: #{color.mix($bg, $text, 95%)};
--color-background-paginate: #{rgba($text, 0.05)};
--color-foreground: #{$text};
--color-highlight: #{$highlight};
--color-highlight-hover: #{color.mix($text, $highlight, 25%)};
--color-highlight-heading: #{color.mix(#fff, $highlight, 20%)};
--color-header: #{rgba($text, 0.4)};
--color-header-shadow: #{rgba($bg, 0.8)};
}
section {
@include color-scheme;
background: var(--color-background);
color: var(--color-foreground);
display: block;
place-content: safe center center;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 40px;
height: 720px;
letter-spacing: 3px;
line-height: 1.4;
padding: 30px 70px;
position: relative;
text-align: center;
width: 1280px;
word-wrap: break-word;
z-index: 0;
/* Definitions for classic bhavior: Users can adopt flex centering by tweaking style `section { display: flex }` */
flex-flow: column nowrap;
align-items: stretch;
&::after {
align-items: flex-end;
background: linear-gradient(
-45deg,
var(--color-background-paginate) 50%,
transparent 50%
);
background-size: cover;
color: var(--color-foreground);
display: flex;
font-size: 0.6em;
height: 80px;
justify-content: flex-end;
padding: 30px;
text-align: right;
text-shadow: 0 0 5px var(--color-background);
width: 80px;
}
&:where(:not(.invert)) {
@import '~highlight.js/styles/color-brewer';
}
&:where(.invert) {
@include color-scheme(#202228, #fff, #60d0f0);
@import '~highlight.js/styles/codepen-embed';
}
> *:first-child,
&[data-header] > :nth-child(2) {
margin-top: 0;
}
> *:last-child,
&[data-footer] > :nth-last-child(2) {
margin-bottom: 0;
}
p,
blockquote {
margin: 0 0 15px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 15px 0 30px;
strong {
color: var(--color-highlight-heading);
font-weight: inherit;
}
&::part(auto-scaling) {
max-height: 660px; // Slide height - padding * 2
}
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.7em;
}
h3 {
font-size: 1.4em;
letter-spacing: 2px;
}
h4 {
font-size: 1.2em;
letter-spacing: 2px;
}
h5 {
font-size: 1em;
letter-spacing: 1px;
}
h6 {
font-size: 0.8em;
letter-spacing: 1px;
}
header,
footer {
color: var(--color-header);
font-size: 0.45em;
left: 70px;
letter-spacing: 1px;
position: absolute;
right: 70px;
text-shadow: 0 1px 0 var(--color-header-shadow);
z-index: 1;
}
header {
top: 30px;
}
footer {
bottom: 30px;
}
a {
color: var(--color-highlight);
text-decoration: none;
&:hover {
color: var(--color-highlight-hover);
text-decoration: underline;
}
}
ul,
ol {
margin: 0 auto;
text-align: left;
}
> ul,
> ol {
margin-bottom: 15px;
}
code {
font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier,
monospace;
letter-spacing: 0;
}
& > code,
*:not(pre) > code {
background: var(--color-background-code);
color: var(--color-foreground);
margin: -0.2em 0.2em 0.2em;
padding: 0.2em;
}
pre {
--preserve-aspect-ratio: xMidYMid meet;
filter: drop-shadow(0 4px 4px rgba(#000, 0.2));
font-size: 70%;
line-height: 1.15;
margin: 15px 0 30px;
text-align: left;
&::part(auto-scaling) {
max-height: 570px;
}
}
pre > code {
background: var(--color-background-code);
box-sizing: content-box;
color: var(--color-foreground);
display: block;
margin: 0 auto;
min-width: 456px; // (Slide width - padding * 2) * 40%
padding: 0.4em 0.6em;
}
&[data-size='4:3'] pre > code {
min-width: 328px;
}
table {
border-collapse: collapse;
margin: 0 auto 15px;
> thead,
> tbody {
> tr {
> td,
> th {
padding: 0.15em 0.5em;
}
}
}
> thead > tr {
> td,
> th {
border-bottom: 3px solid currentcolor;
}
}
> tbody > tr:not(:last-child) {
> td,
> th {
border-bottom: 1px solid currentcolor;
}
}
}
blockquote {
font-size: 90%;
line-height: 1.3;
padding: 0 2em;
position: relative;
z-index: 0;
&::before,
&::after {
content: url('./assets/uncover-quote.svg');
height: auto;
pointer-events: none;
position: absolute;
width: 1em;
z-index: -1;
}
&::before {
left: 0;
top: 0;
}
&::after {
bottom: 0;
right: 0;
transform: rotate(180deg);
}
> *:last-child {
margin-bottom: 0;
}
}
mark {
color: var(--color-highlight);
background: transparent;
}
}
/* "env:userprofile\.vscode\extensions\marp-team.marp-vscode-2.8.0\marp-vscode.css" */
#__marp-vscode {
all: revert;
}
/* Override VS Code default CSS rules reverting to initial
https://github.com/microsoft/vscode/blob/master/src/vs/workbench/contrib/webview/browser/pre/main.js#L53 */
body.marp-vscode {
padding: 0;
}
body.marp-vscode img {
max-width: unset;
max-height: unset;
}
body.marp-vscode a,
body.marp-vscode a:hover,
body.marp-vscode code {
color: unset;
}
body.marp-vscode blockquote {
background: unset;
border-color: unset;
}
@media screen {
body.marp-vscode {
overflow-y: scroll;
}
#__marp-vscode [data-marp-vscode-slide-wrapper] {
margin: 20px;
}
#__marp-vscode svg[data-marpit-svg] {
box-shadow: 0 5px 10px rgb(0 0 0 / 25%);
display: block;
margin: 0;
}
/* Based on https://github.com/microsoft/vscode/blob/master/extensions/markdown-language-features/media/markdown.css */
#code-csp-warning {
background-color: #444;
box-shadow: 1px 1px 1px rgb(0 0 0 / 25%);
color: white;
cursor: pointer;
font-family: sans-serif;
font-size: 12px;
line-height: 22px;
margin: 16px;
padding: 6px;
position: fixed;
right: 0;
text-align: center;
top: 0;
word-wrap: break-word;
}
#code-csp-warning:hover {
text-decoration: none;
background-color: #007acc;
box-shadow: 2px 2px 2px rgb(0 0 0 / 25%);
}
}
@media print {
body.marp-vscode #code-csp-warning {
display: none;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment