mono-opt インストール

centOSによるC#の実行環境を整えるため、monoの公式サイトより、Linux向けインストールを実行します。

mono-project

cd /etc/yum.repos.d
yum install epel-release
wget https://copr.fedoraproject.org/coprs/tpokorra/mono-opt/repo/epel-6/tpokorra-mono-opt-epel-6.repo

yum install monodevelop-opt nunit-opt

. /opt/mono/env.sh
mono --version
[vagrant@localhost yum.repos.d]$ mono --version
Mono JIT compiler version 4.6.0 (Stable 4.6.0.245/746756c Sat Sep 24 06:33:41 UTC 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          yes(3.6.0svn-mono-/)
        GC:            sgen

Monoのコンパイルコマンド

[vagrant@localhost csharp]$ mcs MyApp.cs
[vagrant@localhost csharp]$ ls
MyApp.cs  MyApp.exe
[vagrant@localhost csharp]$ mono MyApp.exe

迷路

左上を迷路のスタート地点、右下を迷路のゴール地点とし、0と1の配列で道と壁を作成しています。迷路作成のアルゴリズムは、棒倒し法で記載しています。考えた人は天才ですね。。

棒倒し法 
1.一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
2.2列目以降の棒を左以外のどれかに倒す
00010
11010
00000
01011
01000

どの位置を0から1に変更するかは、以下のように記載します。
var points = [
 [0, -1],
 [0, 1],
 [1, 0],
 [-1, 0],
];

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>MAZE</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="styles.css">
	<style>
	body {
		font-family: "Century Gothic";
		font-size: 16px;
	}
	#container {
		text-align: center;
		margin: 20px auto;
	}
	#mycanvas {
		background: #AAEDFF;
	}
	.btn {
		margin: 3px auto;
		width: 200px;
		padding: 5px;
		background: #00AAFF;
		color: #ffffff;
		border-radius:3px;
		cursor: pointer;
	}
	.btn:hover{
		opacity: 0.8;
	}

	</style>
</head>
<body>
	<div id="container">
		<canvas width="100" height="100" id="mycanvas">
			Canvasに対応したブラウザを用意してください。
		</canvas>
		<div id="reset" class="btn">RESET</div>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
	<script>
	(function(){

		var Maze = function(col, row){
			this.map = [];
			this.col = col;
			this.row = row;
			this.startX = 0;
			this.startY = 0;
			this.goalX =col - 1;
			this.goalY =row - 1;
			this.points = [
					[0, -1],
					[0, 1],
					[1, 0],
					[-1, 0],
				];


			this.rand = function(n) {
             return Math.floor(Math.random() * (n + 1));
            };
            this.init = function() {
                for (var x = 0; x < col; x++) {
                    this.map&#91;x&#93; = &#91;&#93;;
                    for (var y = 0; y < row; y++) {
                        this.map&#91;x&#93;&#91;y&#93; = 0;
                    }
                }
					for (var x = 1; x < col; x += 2) {
                    for (var y = 1; y < row; y += 2) {
                        this.map&#91;x&#93;&#91;y&#93; = 1;
                    }
                }
                for (var x = 1; x < col; x += 2) {
                    for (var y = 1; y < row; y += 2) {
                        do {
                            if (x === 1) {
                                // 上下左右に倒す
                                var r = this.points&#91;this.rand(3)&#93;;
                            } else {
                                // 左以外に倒す
                                var r = this.points&#91;this.rand(2)&#93;;
                            }
                        } while (this.map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; === 1);
                        this.map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; = 1;
                    }
                }
            };
				this.draw = function() {
                var view = new View();
                view.draw(this);
            };
        };

		var View = function(){
			this.wallSize = 10;
			this.wallColor = '#3261AB';
			this.routeColor = '#ff0088';

			this.canvas = document.getElementById('mycanvas');
			if (!this.canvas || !this.canvas.getContext){
				return false;
			}
			this.ctx = this.canvas.getContext('2d');
			this.draw = function(maze){

				this.canvas.width = (maze.col + 2) * this.wallSize;
				this.canvas.height = (maze.row + 2) * this.wallSize;

				// 上下の壁
				for (var x = 0; x < maze.col + 2; x++) {
		            this.drawWall(x, 0);
		            this.drawWall(x, maze.row + 1);
		        }
				// 左右の壁
				for (var y = 0; y < maze.row + 2; y++) {
		            this.drawWall(0, y);
		            this.drawWall(maze.col + 1, y);
		        }

		        // 迷路の内部
		        for (var x = 0; x < maze.col; x++){
		        	for(var y = 0; y < maze.row; y++){
		        		if(maze.map&#91;x&#93;&#91;y&#93; === 1){
		        			this.drawWall(x + 1, y + 1);
		        		}
		        		if ((x === maze.startX && y === maze.startY) || (x === maze.goalX && y === maze.goalY))
		        		{
		        			this.drawRoute(x + 1, y + 1);
		        		}
		        	}
		        }
			};

				this.drawWall = function(x, y) {
		            this.ctx.fillStyle = this.wallColor;
		            this.drawRect(x, y);
		        };
		        this.drawRoute = function(x, y) {
		            this.ctx.fillStyle = this.routeColor;
		            this.drawRect(x, y);
		        };

		        this.drawRect = function(x, y){
		        		this.ctx.fillRect(
		        	 	x * this.wallSize,
		                y * this.wallSize,
		                this.wallSize,
		                this.wallSize);
		        };

		};

		function reset(){
			var maze = new Maze(13, 13);
			maze.init();
			maze.draw();
		}

		reset();

		document.getElementById('reset').addEventListener('click', function(){
			reset();
		});
		// // 迷路のデータを配列で用意

		// // 0と1の配列で、1を壁と表現する ※奇数でないと道ができない
		// // canvasで描画

		// // 棒倒し法 
		// // 一つとびに壁を作る 1れつ目の棒を上下左右のどちらかに倒す
		// // 2列目以降の棒を左以外のどれかに倒す

		// // 00010
		// // 11010
		// // 00000
		// // 01011
		// // 01000


		// var map = &#91;&#93;;
		// // map&#91;0&#93; = &#91;0, 0, 0&#93;;
		// // map&#91;1&#93; = &#91;0, 1, 1&#93;;
		// // map&#91;2&#93; = &#91;0, 0, 0&#93;;

		// var col = 13; // 奇数
		// var row = 13; // 奇数

		// for (var x = 0; x < col; x++){
		// 	map&#91;x&#93; = &#91;&#93;;
		// 	for (var y = 0; y < row; y++){
		// 		map&#91;x&#93;&#91;y&#93; = 0;
		// 	}
		// }

		// for (var x = 1; x < col; x += 2){
		// 	for(var y = 1; y < row; y += 2){
		// 		map&#91;x&#93;&#91;y&#93; = 1;
		// 	}
		// }

		// var points = &#91;
		// 	&#91;0, -1&#93;,
		// 	&#91;0, 1&#93;,
		// 	&#91;1, 0&#93;,
		// 	&#91;-1, 0&#93;,
		// &#93;;



		// function rand(n){
		// 	return Math.floor(Math.random() * (n + 1));
		// }

		// for (var x = 1; x < col; x += 2){
		// 	for(var y = 1; y < row; y += 2){
		// 		map&#91;x&#93;&#91;y&#93; = 1;
		// 		do {
		// 			if (x === 1){
		// 				var r = points&#91;rand(3)&#93;;
		// 			} else {
		// 				var r = points&#91;rand(2)&#93;;
		// 			}
		// 		} while (map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; === 1);
		// 		map&#91;x + r&#91;0&#93;&#93;&#91;y + r&#91;1&#93;&#93; = 1;
		// 	}
		// }



		// var startX = 0;
		// var startY = 0;
		// var goalX =col - 1;
		// var goalY =row - 1;

		// var wallSize = 10;
		// var wallColor = '#3261AB';
		// var routeColor = '#ff0088';

		// var canvas = document.getElementById('mycanvas');
		// if (!canvas || !canvas.getContext){
		// 	return false;
		// }
		// var ctx = canvas.getContext('2d');

		// canvas.width = (col + 2) * wallSize;
		// canvas.height = (row + 2) * wallSize;

		// // 上下の壁
		// for (var x = 0; x < col + 2; x++) {
  //           drawWall(x, 0);
  //           drawWall(x, row + 1);
  //       }
		// // 左右の壁
		// for (var y = 0; y < row + 2; y++) {
  //           drawWall(0, y);
  //           drawWall(col + 1, y);
  //       }

  //       // 迷路の内部
  //       for (var x = 0; x < col; x++){
  //       	for(var y = 0; y < row; y++){
  //       		if(map&#91;x&#93;&#91;y&#93; === 1){
  //       			drawWall(x + 1, y + 1);
  //       		}
  //       		if ((x === startX && y === startY) || (x === goalX && y === goalY))
  //       		{
  //       			drawRoute(x + 1, y + 1);
  //       		}
  //       	}
  //       }
		// // 壁を描画
		// function drawWall(x, y) {
  //           ctx.fillStyle = wallColor;
  //           drawRect(x, y);
  //       }
  //       function drawRoute(x, y) {
  //           ctx.fillStyle = routeColor;
  //           drawRect(x, y);
  //       }

  //       function drawRect(x, y){
  //       		ctx.fillRect(
  //       	 	x * wallSize,
  //               y * wallSize,
  //               wallSize,
  //               wallSize);
  //       }
	})();
	</script>
</body>
</html>

pinpongゲーム

canvasを使って、x座標、y座標で、setTime関数で動かしています。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Pong Game</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="styles.css">
	<style>
		body {
			margin: 0;
			font-family: "Century Gothic";
			font-size: 16px;
		}
		#container {
			text-align: center;
			margin: 5px auto;
		}
		#mycanvas {
			background: #AAEDFF;
		}
		#btn {
			margin: 3px auto;
			width: 200px;
			padding: 5px;
			background: #00AAFF;
			color: #FFFFFF;
			border-radius: 3px;
			cursor: pointer;
		}
		#btn:hover {
			opacity: 0.8;
		}
	</style>
</head>
<body>
	<div id="container">
		<canvas width="280" height="280" id="mycanvas">
			Canvasに対応したブラウザを用意してください。
		</canvas>
		<div id="btn">START</div>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
	<script>
		$(function(){
			var ctx,
				myPaddle,
				myBall,
				mouseX,
				score,
				scoreLabel,
				isPlaying = false,
				timerId;

			var canvas = document.getElementById('mycanvas');
			if (!canvas|| !canvas.getContext) return false;
			ctx = canvas.getContext('2d');

			var Label = function(x, y){
				this.x = x;
				this.y = y;
				this.draw = function(text){
					ctx.font = 'bold 14px "Century Gothic"';
					ctx.fillStyle = '#00AAFF';
					ctx.textAlign = 'left';
					ctx.fillText(text, this.x, this.y);
				}
			}
			var Ball = function(x, y, vx, vy, r){
				this.x = x;
				this.y = y;
				this.vx = vx;
				this.vy = vy;
				this.r = r;
				this.draw = function(){
					ctx.beginPath();
					ctx.fillStyle = '#FF0088';
					ctx.arc(this.x, this.y, this.r, 0, 2*Math.PI, true);
					ctx.fill();
				};
				this.move = function(){
					this.x += this.vx;
					this.y += this.vy;
					if (this.x + this.r > canvas.width || this.x - this.r < 0){
						this.vx *= -1;
					}
					if (this.y - this.r < 0){
						this.vy *= -1;
					}
					if (this.y + this.r > canvas.height){
						// alert("game over");
						isPlaying = false;
						$('#btn').text('REPLAY?').fadeIn();
					}
				};
				this.checkCollision= function(paddle){
					if ((this.y + this.r > paddle.y && this.y + this.r < paddle.y + paddle.h) &&
						(this.x > paddle.x - paddle.w / 2 && this.x < paddle.x + paddle.w /2)){
						this.vy *= -1;
						score++;
						if (score % 2 === 0){
							this.vx *= 1.3;
							paddle.w *= 0.9;
						}
					}
				}
			}

			var Paddle = function(w, h){
				this.w = w;
				this.h = h;
				this.x = canvas.width / 2;
				this.y = canvas.height - 30;
				this.draw = function(){
					ctx.fillStyle = '#00AAFF';
					ctx.fillRect(this.x - this.w / 2, this.y, this.w, this.h);
				};
				this.move = function(){
					this.x = mouseX - $('#mycanvas').offset().left;
				}
			};

			function rand(min, max){
				return Math.floor(Math.random() * (max - min + 1)) + min;
			}

			function init(){
				score = 0;
				isPlaying = true;
				myPaddle = new Paddle(100, 10);
				myBall = new Ball(rand(50, 250), rand(10, 80), rand(3, 8), rand(3, 8), 6);
				scoreLabel = new Label(10, 25);
				scoreLabel.draw('SCORE: ' + score);
			}
			

			function clearStage(){
				ctx.fillStyle = '#AAEDFF';
				ctx.fillRect(0, 0, canvas.width, canvas.height);
			}

			function update(){
				clearStage();
				scoreLabel.draw('SCORE: ' + score);
				myPaddle.draw();
				myPaddle.move();
				myBall.draw();
				myBall.move();
				myBall.checkCollision(myPaddle);
				timerId =setTimeout(function(){
					update();
				}, 30);
				if(!isPlaying) clearTimeout(timerId);
			}

			$('#btn').click(function(){
				$(this).fadeOut();
				init();
				update();
			});


			$('body').mousemove(function(e){
				mouseX = e.pageX;
			});
		});
	</script>
</body>
</html>

rpsecによるリファクタリング

require 'calc'

RSpec.describe "A calc" do
  before do
    @calc = Calc.new
  end
  it "given 2 and 3, returns 5" do
    expect(@calc.add(2, 3)).to eq(5)
  end
  it "given 5 and 8, returns 13" do
    expect(@calc.add(5, 8)).to eq(13)
  end
end
class Calc
  def add(a, b)
    a + b # 仮実装
  end
end
[vagrant@localhost rspec]$ rspec
..

Finished in 0.00235 seconds (files took 0.11087 seconds to load)
2 examples, 0 failures

describeはcontextを書き換えることも可能。また、コマンドラインはrspec -fdとしても使われる。

pendding

require 'calc'

RSpec.describe Calc do
  describe "when normal mode" do
  it "given 2 and 3, returns 5" do
    calc = Cal.new
    expect(calc.add(2, 3)).to eq(5)
  end
  describe "when graph mode" do
  it "draws graph" do
  end
end

matcher:https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers

    expect(calc.add(2, 3)).to eq(5) #matcher
    expect(calc.add(2, 3)).not_to eq(5) #matcher
    expect(calc.add(2, 3)).to be true #matcher
    expect(calc.add(2, 3)).to be false #matcher
    expect(calc.add(2, 3)).to be > 10 #matcher
    expect(calc.add(2, 3)).to be_between(1, 10).include #matcher
    expect(calc).to respond_to(:add) #matcher
    expect(calc.add(2, 3).integer?).to be true

subject

require 'calc'

RSpec.describe Calc do
  subject(:calc){ Calc.new }
  it {
    # calc = Calc.new
    expect(calc.add(2, 3)).to eq(5)
  }
end

let

context "tax 5%" do
    let(:tax){ 0.05 }
    it { expect(calc.price(100, tax)).to eq(105)}
  end
  context "tax 8%" do
    let(:tax){ 0.08 }
    it { expect(calc.price(100, tax)).to eq(108)}
  end

message expectation

class Calc

  def initialize(logger)
    @logger = logger
  end

  def add(a, b)
    @logger.log
    a + b
  end

end

rspecによるBDD

rspec install

[vagrant@localhost rspec]$ gem install rspec
[vagrant@localhost rspec]$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
[vagrant@localhost rspec]$ rspec -v
3.5.4

TDD/BDD 開発サイクル
1.失敗するテストを書く(Red)
2.最小限のコードを書いてテストをパスさせる(Green)
3.リファクタリング

initフォルダの作成

[vagrant@localhost rspec]$ rspec --init
  create   .rspec
  create   spec/spec_helper.rb

テストファイルは〇〇_spec.rbとし、specフォルダの中に書きます。

1.ミスするコード

RSpec.describe "A calc" do
  it "given 2 and 3, return 5" do
    calc = Calc.new
    epect(calc.add(2, 3)).to eq(5)
  end
end
[vagrant@localhost rspec]$ rspec
F

Failures:

  1) A calc given 2 and 3, return 5
     Failure/Error: calc = Calc.new

     NameError:
       uninitialized constant Calc
     # ./spec/calc_spec.rb:3:in `block (2 levels) in '

Finished in 0.00317 seconds (files took 0.32741 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/calc_spec.rb:2 # A calc given 2 and 3, return 5

2.パスするコードを作成

class Calc
  def add(a, b)
    5 # 仮実装
  end
end
require 'calc'

RSpec.describe "A calc" do
  it "given 2 and 3, returns 5" do
    calc = Calc.new
    expect(calc.add(2, 3)).to eq(5)
  end
end

実行

[vagrant@localhost rspec]$ rspec
.

Finished in 0.00095 seconds (files took 0.10059 seconds to load)
1 example, 0 failures

flexbox

cssのdisplayをflexとし、幅の比率や順番を簡単に記述することができます。

.container {
	width: 300px;
	height: 300px;
	color: #fff;
	background: #eee;
	display: flex;
	/*flex-direction:column-reverse;*/
	/*flex-wrap: wrap;*/
	/*flex-wrap: wrap-reverse;*/
	/*flex-flow: wrap column;*/
	/*justify-content: flex-start;*/
	/*justify-content: flex-end;*/
	/*justify-content: space-between;*/
	/*justify-content: space-around;*/
	/*align-items: flex-start;*/
	/*align-items: flex-end;*/
	/*align-items: flex-center;*/
	/*align-items: stretch;*/
	/*align-content: flex-start;*/
	/*align-content: space-between;*/
	/*align-content: space-around;*/
	justify-content: center;
	align-items: center;

}
.box {
	width:80px;
	height: 80px;
}
/*
flex-grow, shrink, basis, 
margin:auto;
*/
.box-1 { background: tomato; 
	/*flex: 0 1 120px;*/
	/*order: 1;
	align-self: flex-end;*/}
/*.box-2 { background: slategray;
	/*flex: 0 2 120px;*/ }*/
/*.box-3 { background: pink;
	margin-left: auto;
	/*flex: 0 3 120px;*/ }*/

Kotlin 構文2

getter, setter

class User(var name: String){
  var team = "red"
  get(){
    return field.toUpperCase()
  }

  set(value){
    if (value !=""){
      field = value
    }
  }

  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.team)
  tom.sayHi()
}

class override

class AdminUser(name: String): User(name){
  fun sayHello(){
    println("hello $name")
  }
  override fun sayHi(){
    println("what $name")
  }
}
open class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = AdminUser("bob")
  println(bob.name)
  bob.sayHi()
}

アクセス修飾子: privateとpublic

open class User(private var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

class extension

fun User.sayHello(){
  println("hello $name")
}

val User.myName: String
 get() = "I am $name"

class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = User("bob")
  bob.sayHello()
  bob.sayHi()
  println(bob.myName)
}

抽象クラス

abstract class User {
  abstract fun sayHi()
}
class Japanese: User(){
  override fun sayHi(){
    println("こんにちは")
  }
}
class American: User(){
  override fun sayHi(){
    println("hi")
  }
}

fun main(args: Array<String>){
  val tom = American()
  val taro = Japanese()
  tom.sayHi()
  taro.sayHi()
}

interface

interface Sharable{
  // 抽象プロパティ、抽象メソッド、メソッド
  val version: Double
  fun share()
  fun getInfo(){
    println("Share I/F ($version)")
  }
}
class User: Sharable {
  override val version = 1.1
  override fun share(){
    println("Sharing..")
  }
}

fun main(args: Array<String>){
 val user = User()
 user.share()
 user.getInfo()
}

generics

class MyData<T> {
  fun getThree(x: T){
    println(x)
    println(x)
    println(x)
  }
}

fun main(args: Array<String>){
  val i = MyData<Int>()
  i.getThree(32)

  val s = MyData<String>()
  s.getThree("hello")
}

データクラス

data class Point(val x: Int, val y: Int)

fun main(args: Array<String>){
  val p1 = Point(3, 5)
  val p2 = Point(3, 5)
  val p3 = p1.copy()

  println(p1)
  println(if (p1 == p2) "same" else "not same")
}

List

fun main(args: Array<String>){
  val sales: List<Int> = listOf(20, 30, 40)
  println(sales[1])
  println(sales.size)
  for (sale in sales){
    println(sale)
  }
}

set

fun main(args: Array<String>){
  val answers: Set<Int> = setOf(3, 5, 8, 3)
  println(answers)
  println(answers.contains(3))

  val set1 = setOf(1, 3, 5, 8)
  val set2 = setOf(3, 5, 8, 9)

  println(set1.intersect(set2))
  println(set1.union(set2))
  println(set1.subtract(set2))
}

Map

fun main(args: Array<String>){
  val users: Map<String, Int> = mapOf("kobayashi" to 10, "kagawa" to 22, "tanaka" to 33)
  println(users["kobayashi"])
  println(users.size)
  println(users.keys)
  println(users.values)
  println(users.entries)
}

map, filter, foreach

fun main(args: Array<String>){
  val prices = listOf(53.2, 48.2, 32.8)
  prices 
   /*.map { n -> n + 1.08} //*/
   .map { it * 1.08 }
   .filter { it > 50 }
   .forEach { println(it) }
}

例外処理

fun div(a: Int, b: Int){
  try {
    println(a / b)
  } catch(e: ArithmeticException) {
   println(e.message)
  }
}

fun main(args: Array<String>){
  div(3, 0)
}

Nullable型

fun main(args: Array<String>){
  val s: String? = null
  /*println(s)*/

  /*if (s != null){
    println(s.length)
  } else {
    println(null)
  }*/
  println(s?.length ?: -1)
}

Kotlin 構文1

変数

fun main(args: Array<String>){
  val msg: String = "Hello World"
  println(msg)
}

データ型

  val msg: String = "Hello World"
  val c: Char = 'a'
  val i: Int = 100
  val l: Long = 555555555555L
  val d: Double = 234.352
  val f: Float = 123.345
  val flag: Boolean = true

データ演算

val x = 10
  println(x / 3)
  println(x / 3.0)
  println(x % 3)
  var y = 5
  y++
  y--
  println(y)
  var z = 4
  z += 12
  println(z)
  val flag = true
  println(!flag)

文字列

  println("hello " + "world")

  val name = "yoshimoto"
  println("my name is $name")
  println("my score is ${12 + 43}")

  println("hello\n worl\td")

ifの条件分岐

val score = 85
  if (score > 80){
    println("Great!")
  } elseif (score > 60){
      println("good!")
  } else {
    println("soso ..")
  }

when 条件分岐

val num = 3
  when (num){
    0 -> println("zero")
    1 -> println("one")
    in 4.. 10 -> println("many")
    else -> println("other")
  }

while, for

var i = 0
  while (i < 10){
    println("loop: $i")
    i++
  }
for (i in 0..9){
    println(i)
  }

関数

fun sayHi(name: String = "tebes", age: Int = 23){
  println("hi! $name ($age)")
}

fun main(args: Array<String>){
  sayHi("tom", 22)
  sayHi()
}

関数の返り値

fun sayHi(): String {
  return "hi!"
}

fun main(args: Array<String>){
  val msg = sayHi()
  println(msg)
}

class

class User {
  var name = "me!"
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val user = User() // インスタンス
  println(user.name)
  user.sayHi()
}

コンストラクタ引数

class User(var name: String) { //コンストラクタ引数
  /*var name = name*/
  var team = "red"
  init {
    println("instance created: name: $name, team: $team")
  }
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.name)
  tom.sayHi()
}

Kotlin install

JetBrain社が作った、Javaを簡潔に書けるようにした言語です。JVM、Androidで動くことから、Android開発で人気を博しています。

Kotlin

エディタにKotlinのSyntaxを入れます。
kotol

インストールは公式サイトのGettingStarted->Working with the CommandlineよりSDKMAN!をインストールします。

[vagrant@localhost ~]$ curl -s https://get.sdkman.io | bash
[vagrant@localhost ~]$ source "/home/vagrant/.sdkman/bin/sdkman-init.sh"
[vagrant@localhost ~]$ cd kotlin
[vagrant@localhost kotlin]$ sdk version
==== BROADCAST =================================================================
* 15/11/16: Kotlin 1.0.5-2 released on SDKMAN! #kotlin
* 14/11/16: Gradle 3.2 released on SDKMAN! #gradle
* 10/11/16: Grails 3.2.3 released on SDKMAN! #grailsfw
================================================================================
SDKMAN 5.1.7+91
[vagrant@localhost kotlin]$ sdk install kotlin

インストールが終了したら、動作確認しましょう。

[vagrant@localhost kotlin]$ kotlin -version
Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
[vagrant@localhost kotlin]$ kotlinc
Welcome to Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
Type :help for help, :quit for quit
>>> 1 + 2
3
fun main(args: Array<String>){
  println("Hello World")
}
[vagrant@localhost kotlin]$ kotlinc myapp.kt -include-runtime -d myapp.jar
[vagrant@localhost kotlin]$ ls
myapp.jar  myapp.kt
[vagrant@localhost kotlin]$ java -jar myapp.jar
Hello World

scala 構文4

パターンマッチ

case class Point(x: Int, y: Int)

object MyApp {

  def main(args: Array[String]): Unit = {

   var points = List(
    Point(5, 3),
    Point(0, 0),
    Point(3, 4)
   )
   points.foreach(_ match{
    case Point(0, 0) => println("original")
    case Point(5, _) => println("right edge")
    case Point(x, y) => println(s"$x:$y")
   })

  }

}

option型のエラー処理

object MyApp {

  def main(args: Array[String]): Unit = {
  val scores = Map("yoshimoto" -> 55, "kimoto" -> 65)
  scores.get("tanaka") match {
   case Some(v) => println(v)
   case None => println("key not found")
  }
  }

}

Eitherによるエラー処理

object MyApp {

 // Error Either - right, left

  def div(a: Int, b: Int): Either[String, Int] = {
  if (b == 0) Left("Zero div error!")
  else Right(a / b)
  }
  def main(args: Array[String]): Unit = {

   div(10, 2) match {
   case Right(n) => println(n)
   case Left(s) => println(s)
   }

  }

}