2016-12-21 5 views
0

通常、このコードを書くと、Swift 3コンパイラは、void関数から値を返すときに間違ったメッセージを表示します。

func test1() { 
    return CGPoint.zero 
} 

コンパイラはあなたに非常にいいです、ボイド機能

予期せぬvoid以外の戻り値を教えてくれます。誰もが間違ったことを知っています。

しかし、このコードは、コンパイラが別の何かを言うことになります:

func test2() { 
    let a: CGFloat = 1 
    return CGPoint(x: 0.0, y: a) 
} 

コンパイラ今言う:

型の初期化子を呼び出すことができないタイプの引数リストで「するCGPoint」「( (x:Double、y:CGFloat) '

注:「CGPoint」のオーバーロードは、これらの部分一致するパラメータリスト(x:CGFloat、y:CGFloat)、(x:Double、y:Double)で存在します。

今私は混乱しています。

なぜコンパイラは、void関数に値を返すことについて言及していない、と代わりに完全に罰金である、(x: 0.0, y: a)CGPoint.initを呼び出すことに文句を言いますか? 0.0ので

リテラルフロートであり、そしてCGFloatExpressibleByFloatLiteralに準拠したBinaryFloatingPointに準拠し、0.0は、コンパイル時にCGFloatに変換されます。その結果、イニシャライザCGPoint(x: CGFloat, y: CGFloat)が使用されているはずです。コンパイラはなぜCGPoint(x: Double, y: CGFloat)で初期化できないと不平を言いますか?

コンパイラが私が値を返していないことを見て、表現を取り除くのをやめて、0.0CGFloatに変換されていないことがわかったからです。しかし、その場合、コンパイラは何かにvoid関数の値を返すと言っているはずです。

これはバグですか?

+6

CGPoint(x :, y:)には少なくとも3つのオーバーロードがあります。コンパイラが 'Void'を返すものを見つけようとすると失敗し、そのエラーメッセージを出力するようです。 –

+0

私は今参照してください!ありがとうございました! @MartinR – Sweeper

答えて

1

CGPointは同じ引数名を持つ3つのオーバーロードされた初期化子があります

public init(x: CGFloat, y: CGFloat) 
public init(x: Double, y: Double) 
public init(x: Int, y: Int) 

あなたがここに

let v: Void = CGPoint(x: 1.0, y: 2) 
// error: cannot invoke initializer for type 'CGPoint' with an argument list of type '(x: Double, y: Int)' 
// note: overloads for 'CGPoint' exist with these partially matching parameter lists: (x: Int, y: Int), (x: Double, y: Double) 

と同じエラーメッセージが表示されます効果を示す別の例である:

struct A { 
    init(x: Double, y: Double) { } 
} 

struct B { 
    init(x: Double, y: Double) { } 
    init(xi: Int, yi: Int) { } 
} 

struct C { 
    init(x: Double, y: Double) { } 
    init(x: Int, y: Int) { } 
} 

let v1: Void = A(x: 1, y: 2.0) 
// error: cannot convert value of type 'A' to specified type 'Void' (aka '()') 

let v2: Void = B(x: 1, y: 2.0) 
// error: cannot convert value of type 'B' to specified type 'Void' (aka '()') 

let v3: Void = C(x: 1.0, y: 2.0) 
// error: cannot convert value of type 'C' to specified type 'Void' (aka '()') 

let v4: Void = C(x: 1, y: 2.0) 
// error: cannot invoke initializer for type 'C' with an argument list of type '(x: Int, y: Double)' 

最後の行のみC(x: 1, y: 2.0)一致2つのイニシャライザ。 I コンパイラが両方を照合しようとした場合、 の戻り値はVoidに変換されず、したがって異なる エラーメッセージが出力されます。

エラーメッセージはそれほど役に立ちませんので、 にバグレポートhttp://bugs.swift.orgを提出することをお勧めします。

+0

私は今理解しています。私はバグ報告をします! – Sweeper

+0

https://bugs.swift.org/browse/SR-3470?filter=-2 – Sweeper

関連する問題