質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

1742閲覧

Swift 戻り値を指定しているのに,戻り値がない旨のエラーが出る

maru.wk

総合スコア30

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/12/12 09:28

Swiftに関する質問です。
戻り値のある関数を作成し,指定した型でreturnさせたのですが,Missing return in a function expected to return '[UInt8]'というエラーが出ます。いろいろいじってみたのですが,解決せず,どうすれば良いのかわかりません。

swift

1//各ピクセルからRGB情報を抽出し,配列として保存するクラス 2class rgbArray { 3 4 var width : Int 5 var height : Int 6 var pixelData : Data 7 var bytesPerRow : Int 8 let bytesPerPixel = 4 9 10 init? (myImage: CGImage) { 11 12 pixelData = myImage.dataProvider!.data! as Data 13 width = myImage.width 14 height = myImage.height 15 bytesPerRow = myImage.bytesPerRow 16 print(myImage.bitsPerPixel) 17 18 } 19 20 func getPixelColorFromUIImage(x: Int,y: Int) -> [UInt8] { 21 22 let pixelInfo: Int = (Int(bytesPerRow) * y + x * 4) 23 let r = Double(pixelData[pixelInfo]) 24 let g = Double(pixelData[pixelInfo+1]) 25 let b = Double(pixelData[pixelInfo+2]) 26 27 var rgb : [UInt8] 28 rgb = [UInt8(r),UInt8(g),UInt8(b)] 29 30 31 return rgb 32 33 } 34 35} 36 37 38//入力画像から出力画像のRGB配列を作成するクラス 39class Transformation { 40 41 var outSizeX : Int 42 var outSizeY : Int 43 var theta2 : Double 44 var tanTheta : Double 45 var dIn : Double 46 var fIn : Double 47 var dOut : Double 48 var fOut : Double 49 var InCenterX : Double 50 var InCenterY : Double 51 var outCenterX : Double 52 var outCenterY : Double 53 var inputImage1 : CGImage 54 55 56 init? (inputImage: CGImage, OutSizeX : Int, OutSizeY : Int, Theta2 : Double) { 57 outSizeX = OutSizeX 58 outSizeY = OutSizeY 59 theta2 = Theta2 60 tanTheta = tan(0.5*theta2*(Double.pi)/180) 61 dIn = 0.5*sqrt(pow(Double(inputImage.width),2) + pow(Double(inputImage.height), 2)) 62 fIn = dIn / tanTheta 63 dOut = 0.5*sqrt(pow(Double(outSizeX),2) + pow(Double(outSizeY), 2)) 64 fOut = 2*dOut / M_PI 65 inputImage1 = inputImage 66 InCenterX = 0.5*Double(inputImage.width) 67 InCenterY = 0.5*Double(inputImage.height) 68 outCenterX = 0.5*Double(outSizeX) 69 outCenterY = 0.5*Double(outSizeY) 70 } 71 //出力画像のRGB配列を作成する関数 72 func createRGB() -> [UInt8]{ 73 74 var yOutX : Double 75 var yOutY : Double 76 var yOut : Double 77 var inPixelI : Int 78 var inPixelJ : Int 79 var yIn : Double 80 var scale : Double 81 82 //全ピクセルに対して処理を行う 83 for y in 0..<outSizeY{ 84 for x in 0..<outSizeX{ 85 86 //出力画像の中心座標から任意のピクセルまでの距離 87 yOutX = Double(x) - outCenterX + 0.5 88 yOutY = Double(y) - outCenterY + 0.5 89 yOut = sqrt(pow(yOutX,2) + pow(yOutY,2)) 90 91 //rgbArrayをインスタンス化し,outputRGBに出力画像の任意のピクセルのRGB情報を格納 92 var outputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: x, y: y) 93 94 //yOutの値から,条件分岐 95 if yOut == 0 { 96 inPixelI = Int(round(InCenterX-0.5)) 97 inPixelJ = Int(round(InCenterY-0.5)) 98 //求めた入力画像の座標におけるピクセルのRGB情報を,出力画像のピクセルのRGB情報に上書き 99 let centerInputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: inPixelI, y: inPixelJ) 100 outputRGB?[0] = (centerInputRGB?[0])! 101 outputRGB?[1] = (centerInputRGB?[1])! 102 outputRGB?[2] = (centerInputRGB?[2])! 103 104 }else { 105 //射影変換を行い,出力画像でのyOutが入力画像ではどのような値になるか調べる 106 yIn = fIn*tan(yOut/fOut) 107 scale = yIn / yOut 108 //yInから,出力画像の任意のピクセルに対応する,入力画像のピクセルの座標を調べる 109 inPixelI = Int(round(yOutX*scale + InCenterX - 0.5)) 110 inPixelJ = Int(round(yOutY*scale + InCenterY - 0.5)) 111 //入力画像のピクセルのRGB情報を得る 112 let inputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: inPixelI, y: inPixelJ) 113 114 if (inPixelI < Int(inputImage1.width)) && (inPixelJ < Int(inputImage1.height)) { 115 outputRGB?[0] = (inputRGB?[0])! 116 outputRGB?[1] = (inputRGB?[1])! 117 outputRGB?[2] = (inputRGB?[2])! 118 }else { 119 outputRGB?[0] = 0 120 outputRGB?[1] = 0 121 outputRGB?[2] = 0 122 } 123 } 124 125 return (outputRGB)! 126 } 127 } 128 }

エラーが出るのは最後の,return (outputRGB)!の所です。まだまだSwiftに不慣れで雑なコードになっておりますが,どなたかよろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

outSizeXやoutSizeYが0のときにreturn (outputRGB)!が実行されません。

投稿2017/12/12 09:43

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maru.wk

2017/12/13 01:49

ご回答ありがとうございます。つまりは,outSizeXやoutSizaYが0でないことを何かしらで保証すれば良い,という解釈であっておりますでしょうか?
fuzzball

2017/12/13 02:09

「保証」というのが具体的にどういうことなのか分かりませんが、outSizeXやoutSizaYが0のときでも何らかの値を返さないといけません。createRGB() は、どんな場合でも [UInt8] を返さないといけないんです。 例えば return [] でカラ配列を返すとかです。
maru.wk

2017/12/13 03:02

理解が追いつかず,申し訳ありません。outSizeXとoutSizeYが0でも[Uint8]を返す必要があるが,0だと[Uint8]配列を返すことができないため,エラーが起きる,ということであれば,outSizeXやoutSizeYにあらかじめ何かしらの値を与えておけば,エラーは出ないと解釈したのですが,あってますでしょうか?
maru.wk

2017/12/13 03:02

何度も申し訳ありません
fuzzball

2017/12/13 03:36

>>0だと[Uint8]配列を返すことができないため,エラーが起きる 違います。「返すことができない」からではなく「返していない」からエラーが出ているのです。 >>outSizeXやoutSizeYにあらかじめ何かしらの値を与えておけば というのは実行時の話です。ビルドエラーなのですから、ビルドが通るように修正しないといけません。
guest

0

ベストアンサー

for文を二回かいたネスト構造で、さらにコードが長く可読性がかなり悪いのでこのようなことになっているかと思われます。

もう少し簡単にかくとこのような感じではないでしょうか

func test() -> [Int] { var i = 0 if i == 0 { var outSize: [Int] if i == 0 { } return outSize } }

このメソッド(test())の問題として、if文という条件式の中でしか、返り値を設定しておらず、条件式を通過しない場合の返り値が考慮されていません。そのためエラーが出ます。

なの最後に以下のように付け加えれば直るのではないでしょうか?

func test() -> [Int] { var i = 0 if i == 0 { var outSize: [Int] if i == 0 { } return outSize } return [0] }

今自分があげたような構造とほぼ同じような形になっているかと思うので確認してみてください。
基本的にコードが長くなったらメソッドで切り出してあげたほうがいいかと。
参考にならなかったら無視しちゃって大丈夫ですw

投稿2017/12/26 19:17

komo_ta

総合スコア275

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maru.wk

2018/01/04 02:42

返答が大変遅くなり申し訳ありません。 このようなやり方があるのですね! 今から試してみます。丁寧なご解説ありがとうございます。
maru.wk

2018/01/07 07:14

おかげさまで解決することができました。 if文の中のみの戻り値では不完全なのですね! 基本的なことで失礼いたしました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問