UbuntuにPythonコマンドが無い場合

WSL上のUbuntuにpythonコマンドがありませんでした。

$ ls -l /usr/bin/python*
lrwxrwxrwx 1 root root       9  3月 13  2020 /usr/bin/python3 -> python3.8
-rwxr-xr-x 1 root root 5490448  3月 15 21:22 /usr/bin/python3.8

python3コマンドはあったので手動でリンクを貼ろうかとも考えたんですが、調べたら次のようなパッケージがありました。
インストールしてみました。

$ sudo apt install python-is-python3
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  python-is-python3

以下略

すると、無事pythonコマンドのリンクが貼られてました。

$ ls -l /usr/bin/python*
lrwxrwxrwx 1 root root       7  4月 15  2020 /usr/bin/python -> python3
lrwxrwxrwx 1 root root       9  3月 13  2020 /usr/bin/python3 -> python3.8
-rwxr-xr-x 1 root root 5490448  3月 15 21:22 /usr/bin/python3.8

AndroidStudioのエミュレーターが調子悪くなったら

AndroidStudioのエミュレーターが調子悪くなりました。

AndroidStudioのメニューアイコンから再起動しようと思っても何も反応せず、パソコンを再起動しても変わりませんでした。

この場合は、次のようにしてエミュレーターをリセットするといいです。

まず、AndroidStudioのターミナル(普通は左下のタブにあります)からadbを使って次のコマンドを実行します。

> adb devices
List of devices attached
emulator-5554   device

ここで表示されるデバイス名を指定して、次のコマンドを実行するとエミュレーターとの接続が終了します。

> adb -s emulator-5554 emu kill
OK: killing emulator, bye bye
OK

次に、AndroidStudioのDeviceManagerから該当のエミュレーターを選びWipe Dataを実行します。

AndroidStudioのエミュをWipeData
AndroidStudioのエミュをWipeDataする

その後エミューレーターを起動すると初期化された状態で起動するので日本語化の設定などをやりなおしてください。

[Kotlin] JavaからKotlinを呼び出す

※翻訳がわかりにくい場合は原文を読んでください。

KotlinコードはJavaから簡単に呼び出すことができます。

プロパティ

Kotlinプロパティは、次のJava要素にコンパイルされます。

  • get接頭辞を前置することによって計算された名前を持つgetterメソッド
  • set接頭辞を前置することによって計算された名前を持つsetterメソッド(varプロパティに対してのみ)
  • プロパティ名と同じ名前のプライベートフィールド(バッキングフィールドを持つプロパティのみ)

例えば、 var firstName: String は以下のJava宣言にコンパイルされます

private String firstName;

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

プロパティの名前が isで始まる場合、別の名前マッピング規則が使用されます。ゲッターの名前は次のようになります。 プロパティ名と同じで、setterの名前は issetに置き換えることで得られます。 たとえば、プロパティisOpenの場合、getterはisOpen()と呼ばれ、setterはsetOpen()と呼ばれます。 このルールは、 Booleanだけでなくあらゆるタイプのプロパティに適用されます。

パッケージレベルの関数

拡張機能を含む org.foo.barパッケージ内のexample.ktファイル内で宣言されたすべての関数とプロパティは、 org.foo.bar.ExampleKt`という名前のJavaクラスの静的メソッドにコンパイルされます。

// example.kt
package demo

class Foo

fun bar() {
}
// Java
new demo.Foo();
demo.ExampleKt.bar();

生成されたJavaクラスの名前は、 @JvmNameアノテーションを使用して変更できます。

@file:JvmName("DemoUtils")

package demo

class Foo

fun bar() {
}
// Java
new demo.Foo();
demo.DemoUtils.bar();

生成された同じJavaクラス名を持つ複数のファイルを持つ(同じパッケージで同じ名前または同じ @JvmNameアノテーション)は通常エラーです。 ただし、コンパイラには、指定された名前を持ち、その名前を持つすべてのファイルのすべての宣言が含まれる単一のJavaファサードクラスを生成する機能があります。 このようなファサードの生成を可能にするには、すべてのファイルで@JvmMultifileClassアノテーションを使用します。

// oldutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package demo

fun foo() {
}
// newutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package demo

fun bar() {
}
// Java
demo.Utils.foo();
demo.Utils.bar();

インスタンスフィールド

JavaのフィールドとしてKotlinプロパティを公開する必要がある場合は、それを @JvmFieldアノテーションでアノテートする必要があります。 フィールドは、基になるプロパティと同じ可視性を持ちます。 @JvmFieldにバッキングフィールドがある、プライベートでない、 openoverrideconst修飾子を持たず、委譲されたプロパティでない場合、プロパティに注釈を付けることができます。

class C(id: String) {
    @JvmField val ID = id
}
// Java
class JavaClient {
    public String getID(C c) {
        return c.ID;
    }
}

Late-Initialized プロパティもフィールドとして公開されます。 フィールドの可視性は、 lateinitプロパティーセッターの可視性と同じになります。

静的フィールド

名前付きオブジェクトまたはコンパニオンオブジェクトで宣言されたKotlinプロパティは、名前付きオブジェクトまたはコンパニオンオブジェクトを含むクラスの静的なバッキングフィールドを持ちます。

通常、これらのフィールドはプライベートですが、次のいずれかの方法で公開することができます。

  • @JvmField アノテーション
  • lateinit 修飾子
  • const 修飾子

このようなプロパティに @JvmFieldを付けると、プロパティ自体と同じ可視性を持つ静的フィールドになります。

class Key(val value: Int) {
    companion object {
        @JvmField
        val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
    }
}
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class

オブジェクトまたはコンパニオンオブジェクトの late-initialized プロパティはプロパティセッターと同じ可視性を持つ静的なバッキングフィールドを持っています。

object Singleton {
    lateinit var provider: Provider
}
// Java
Singleton.provider = new Provider();
// public static non-final field in Singleton class

constでアノテーションされたプロパティ(クラス内とトップレベル)は、Javaの静的フィールドに変換されます

// file example.kt

object Obj {
    const val CONST = 1
}

class C {
    companion object {
        const val VERSION = 9
    }
}

const val MAX = 239

Javaの場合:

int c = Obj.CONST;
int d = ExampleKt.MAX;
int v = C.VERSION;

静的メソッド

前述のように、Kotlinは静的メソッドとしてパッケージレベルの関数を表します。 これらの関数に @JvmStaticと注釈を付けると、Kotlinは名前付きオブジェクトやコンパニオンオブジェクトで定義された関数の静的メソッドを生成することもできます。 このアノテーションを使用すると、コンパイラはオブジェクトの囲むクラスに静的メソッドを生成し、オブジェクト自体にインスタンスメソッドを生成します。 例えば、

class C {
    companion object {
        @JvmStatic fun foo() {}
        fun bar() {}
    }
}

今、 foo()はJavaでは静的ですが、 bar()は静的ではありません

C.foo(); // works fine
C.bar(); // error: not a static method
C.Companion.foo(); // instance method remains
C.Companion.bar(); // the only way it works

名前付きオブジェクトと同じ

object Obj {
    @JvmStatic fun foo() {}
    fun bar() {}
}

Javaの場合:

Obj.foo(); // works fine
Obj.bar(); // error
Obj.INSTANCE.bar(); // works, a call through the singleton instance
Obj.INSTANCE.foo(); // works too

@JvmStaticアノテーションは、オブジェクトまたはコンパニオンオブジェクトのプロパティに適用することもできます。そのため、getterメソッドとsetterメソッドは、そのオブジェクトまたはコンパニオンオブジェクトを含むクラスの静的メンバになります。

## 可視性

Kotlinの可視性は、次のようにJavaにマッピングされます。

  • privateメンバはprivateメンバにコンパイルされます。
  • privateトップレベル宣言はパッケージローカル宣言にコンパイルされます。
  • protectedprotectedのままです(Javaは同じパッケージ内の他のクラスから保護されたメンバーにアクセスすることができます Kotlinはそうしないので、Javaクラスはコードへのより広いアクセスを持つでしょう)。
  • internal宣言はJavaでpublicになります。 internalクラスのメンバは、誤ってJavaからそれらを使用するのを困難にし、Kotlinの規則に従ってお互いに見えない同じ署名を持つメンバのためにオーバーロードを許容するために、名前修飾を受けます。
  • publicpublicのままです。

## Kクラス

時々 KClass型のパラメータでKotlinメソッドを呼び出す必要があります。 ClassからKClassへの自動変換はありませんので、 Class <T> .kotlin拡張プロパティと同等のものを呼び出すことで手動で行う必要があります:

kotlin.jvm.JvmClassMappingKt.getKotlinClass(MainView.class)

@JvmNameで署名の衝突を処理する

Kotlinには、バイトコードとは異なるJVM名が必要な名前付き関数があります。 最も顕著な例は型消去のために起こります。

fun List<String>.filterValid(): List<String>
fun List<Int>.filterValid(): List<Int>

これら2つの関数は、JVMのシグネチャが同じ filterValid(Ljava/util/List;)Ljava/util/List; であるため、並行して定義することはできません。 Kotlinに同じ名前をつけたいのであれば、そのうちの1つ(または両方)に @JvmNameを付けて、別の名前を引数として指定することができます。

fun List<String>.filterValid(): List<String>

@JvmName("filterValidInt")
fun List<Int>.filterValid(): List<Int>

Kotlinからは filterValidと同じ名前でアクセスできますが、JavaからはfilterValidfilterValidIntがあります。

同じトリックが、 getX()関数の横にプロパティ xを持つ必要があるときに適用されます。

val x: Int
    @JvmName("getX_prop")
    get() = 15

fun getX() = 10

オーバーロード生成

通常、デフォルトのパラメータ値を持つKotlin関数を記述すると、Javaでは完全なシグネチャとしてのみ表示され、すべてのパラメータが表示されます。複数のオーバーロードをJava呼び出し側に公開する場合は、 @JvmOverloadsアノテーションを使用できます。

注釈は、コンストラクタ、静的メソッドなどにも使用できます。インタフェースで定義されたメソッドを含む抽象メソッドでは使用できません。

class Foo @JvmOverloads constructor(x: Int, y: Double = 0.0) {
    @JvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
        ...
    }
}

デフォルト値を持つすべてのパラメータについて、これは追加のオーバーロードを1つ生成します。このオーバーロードには、このパラメータがあり、パラメータリストのその右側のすべてのパラメータが削除されます。この例では、次のものが生成されます。

// Constructors:
Foo(int x, double y)
Foo(int x)

// Methods
void f(String a, int b, String c) { }
void f(String a, int b) { }
void f(String a) { }

Secondary Constructorsで説明されているように、クラスにすべてのコンストラクタパラメータのデフォルト値がある場合は、引数なしのpublicコンストラクタが生成されます。これは、@JvmOverloadsアノテーションが指定されていなくても機能します。

チェックされた例外

上記のように、Kotlinは例外をチェックしていません。 したがって、通常、Kotlin関数のJavaシグネチャは例外がスローされたことを宣言しません。 したがって、Kotlinに次のような関数があるとします。

// example.kt
package demo

fun foo() {
    throw IOException()
}

そして、Javaから呼び出して例外をキャッチしたい

// Java
try {
  demo.Example.foo();
}
catch (IOException e) { // error: foo() does not declare IOException in the throws list
  // ...
}

foo()IOExceptionを宣言しないので、Javaコンパイラからエラーメッセージが出ます。 この問題を回避するには、Kotlinで @Throwsアノテーションを使用してください。

@Throws(IOException::class)
fun foo() {
    throw IOException()
}

Null-safety

JavaからKotlin関数を呼び出すときに、null以外のパラメータとして null{: .keyword } を渡すことができなくなります。 だからこそ、Kotlinは、非nullを期待するすべてのパブリック関数のランタイムチェックを生成します。 このようにして、Javaコードで即座に NullPointerExceptionを取得します。

バリアントジェネリックス

Kotlinクラスが 宣言サイトの分散 を利用する場合、 その使用法がJavaコードからどのように見えるかという2つのオプションがあります。次のクラスとそれを使用する2つの関数があるとしましょう。

class Box<out T>(val value: T)

interface Base
class Derived : Base

fun boxDerived(value: Derived): Box<Derived> = Box(value)
fun unboxBase(box: Box<Base>): Base = box.value

これらの関数をJavaに変換する素朴な方法は次のとおりです。

Box<Derived> boxDerived(Derived value) { ... }
Base unboxBase(Box<Base> box) { ... }

問題は、Kotlinでは unboxBase(boxDerived("s")) と言うことができますが、Javaでは不可能です。なぜなら、JavaではクラスBoxはパラメータT不変であるため、従って Box<Derived>Box<Base> のサブタイプではありません。 Javaで動作させるには、次のように unboxBaseを定義する必要があります。

Base unboxBase(Box<? extends Base> box) { ... }  

ここでは、Javaのワイルドカード型? extends Base)を使用して、使用サイトの分散によって宣言サイトの分散をエミュレートします。なぜなら、それはJavaが持つすべてのものだからです。

Kotlin APIをJavaで動作させるために、パラメータとして現れるときに、共変に定義された Box(反逆的に定義されたFooの場合は Foo<? super Bar>)のBox<Super>Box<? extends Super>として生成します。戻り値の場合、ワイルドカードは生成されません。そうしなければ、Javaクライアントは対処する必要があります(一般的なJavaコーディングスタイルに反します)。したがって、この例の関数は実際には次のように変換されます。

// return type - no wildcards
Box<Derived> boxDerived(Derived value) { ... }

// parameter - wildcards 
Base unboxBase(Box<? extends Base> box) { ... }

注意:引数の型がfinalの場合、通常はワイルドカードを生成する点はないので、どの位置にあっても Box <String>は常に Box <String>です。

デフォルトで生成されないワイルドカードが必要な場合は、 @JvmWildcardアノテーションを使用できます。

fun boxDerived(value: Derived): Box<@JvmWildcard Derived> = Box(value)
// is translated to 
// Box boxDerived(Derived value) { ... }

一方、生成されるワイルドカードが必要ない場合は、 @ JvmSuppressWildcardsを使用することができます。

fun unboxBase(box: Box<@JvmSuppressWildcards Base>): Base = box.value
// is translated to 
// Base unboxBase(Box<Base> box) { ... }

注意: @JvmSuppressWildcardsは、個々の型引数だけでなく、関数やクラスなどの宣言全体でも使用でき、その中のすべてのワイルドカードを抑止できます。

Nothing型の翻訳

Nothing は、Javaに自然な対応がないため特別です。 実際、 java.lang.Voidを含むすべてのJava参照型は値としてnullを受け取り、 Nothingはそれを受け入れません。したがって、このタイプはJavaの世界では正確に表現できません。 これがKotlinが Nothing型の引数が使われる生の型を生成する理由です:

fun emptyList(): List<Nothing> = listOf()
// is translated to
// List emptyList() { ... }

[Swift] GCD関連 [Swift4対応]

  • キューの作成

(Swift2まで)

let queue1 = dispatch_queue_create("arrayQ", DISPATCH_QUEUE_SERIAL)
let queue2 = dispatch_queue_create("arrayQ", DISPATCH_QUEUE_CONCURRENT)

(Swift3以降)

let queue1 = DispatchQueue(label: "arrayQ")
let queue2= DispatchQueue(label: "arrayQ", attributes: .concurrent)

(Swift2まで)

let queue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
let queue4 = dispatch_get_main_queue()

(Swift3以降)

let queue3 = DispatchQueue.global(qos:DispatchQoS.QoSClass.background)
let queue4= DispatchQueue.main

  • グループの作成

(Swift2まで)

let group = dispatch_group_create()

(Swift3以降)

let group = DispatchGroup()

  • グループのwait

(Swift2まで)

dispatch_group_wait(group, dispatch_time_t(DISPATCH_TIME_FOREVER))

(Swift3以降)

group.wait(wallTimeout: .distantFuture)

  • 同期処理

(Swift2まで)

dispatch_sync(queue, {() in
...
}

(Swift3以降)

queue.sync {() in
...
}

  • 非同期処理

(Swift2まで)

dispatch_async(queue, {() in
...
}

(Swift3以降)

queue.async {() in
...
}

(Swift2まで)

dispatch_barrier_async(queue, {() in
...
}

(Swift3以降)

queue.async(flags: .barrier) {() in
...
}

  • セマフォ宣言

(Swift2まで)

let semaphore:dispatch_semaphore_t

(Swift3以降)

let semaphore:DispatchSemaphore

  • セマフォの作成

(Swift2まで)

semaphore = dispatch_semaphore_create(Int)

(Swift3以降)

semaphore = DispatchSemaphore(value: Int)

  • セマフォのwait

(Swift2まで)

if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) == 0) {
...
}

(Swift3以降)

if (semaphore.wait(timeout:.distantFuture) == .success) {
...
}

  • セマフォのsignal

(Swift2まで)

dispatch_semaphore_signal(semaphore)

(Swift3以降)

semaphore.signal()

[Swift][Error]Argument labels ‘(_:)’ do not match any available overloads

・エラーメッセージ
Argument labels ‘(_:)’ do not match any available overloads

・エラー例

let num = 3
var nsnum = NSNumber(num)
// => Argument labels ‘(_:)’ do not match any available overloads

・原因
メソッドに必要なラベルが存在しないために発生します

・対策
ラベルなしで実行可能なメソッドも多いですが必要なメソッドもあるので、ドキュメントを見ながら適切に設定しましょう。

let num = 3
var nsnum = NSNumber(value: num)

[Swift] Swift3で対象範囲を指定して配列内の要素を削除する

ArrayクラスのremoveSubrangeメソッドを使うと以下のように削除することが出来ます。

var t = [“zero”, “one”, “two”, “three”, “four”]
t.removeSubrange(1…2)
print(t)
// => [“zero”, “three”, “four”]

[Swift] Swift3でArrayにremoveObjectを実装する

NSArrayにはremoveObjectというインデックスではなくオブジェクトを指定して配列内の該当する要素を削除するメソッドがあります。

同じものがSwiftのArrayにもあるかと思ったのですが無く困ってましたが、以下のようにextensionを使ってArrayを拡張すれば対応可能になります。

extension Array where Element: Equatable {
    // 先頭のオブジェクトのみ削除
    mutating func remove(firstObject: Element) {
        if let index = index(of: firstObject) {
            remove(at: index)
        }
    }

    // すべてのオブジェクトを削除
    mutating func remove(object: Element) {
        if let index = index(of: object){
            self.remove(at: index)
            self.remove(object: object)
        }
    }
}

これをファイルの先頭に書いておくと、以下の様にArrayを拡張してオブジェクトを指定して配列内の要素を削除することが出来ます。

var test = Array<String>()
test=[“apple”, “orange”, “Orange”, “apple”]

test.remove(firstObject: “apple”)
// => [“orange”, “Orange”, “apple”]
// 先頭のappleのみ削除され、2つ目以降のappleは削除されない。

test.remove(object: “apple”)
// => [“orange”, “Orange”]
// すべてのappleが削除される。

[Swift][Error] Value of type ‘[*]’ has no member ‘*’

・エラーメッセージ
Value of type ‘[]’ has no member ‘

・エラー例

var x:[Int] = [1,2,3]
if x.containsObject(2) {
 print(“x contains 2”)
}
// => Value of type ‘[Int]’ has no member ‘containsObject’

・原因
存在しないメソッドや変数を利用しようとした場合に発生する。

・対策
NSArrayをArrayに書き換えた場合など、つい同じ名前のメソッドが存在すると思いがちだがメソッド名変わっていたりするので、マニュアルを確認して適切に変更する。

var x:[Int] = [1,2,3]
if x.contains(2) {
 print(“x contains 2”)
}

[Swift][Error] Cannot assign value of type ‘[AnyObject]’ to type *

・エラーメッセージ
Cannot assign value of type ‘[AnyObject]’ to type *

・エラー例

var x:[Int]
var y:[AnyObject] = [1,2,3]
x = y
// => Cannot assign value of type ‘[AnyObject]’ to type ‘[Int]’

・原因
上記の場合、AnyObject型のコレクション(配列や辞書)をInt型のコレクションに格納しようとしたため

・対策
代入前に as! を使ってダウンキャストを行う

var x:[Int]
var y:[AnyObject] = [1,2,3]
x = y as! [Int]

[Swift][Error] Can’t convert value of type * to expected argument type *

・エラーメッセージ
Can’t convert value of type * to expected argument type *

・エラー例

var y:Double
var x:Int = 10
y = 10 + x
// => Can’t convert value of type ‘Int’ to expected argument type ‘Double’

・原因
上記の場合、Double型の変数にInt型の数値を格納しようとしたため

・対策
代入前に型の変換を行う

var y:Double
var x:Int = 10
y = Double(10 + x)