56884


Kotlinにある `mapNotNull` を実装しようとして（Swiftなので名前は`mapNotNil`の方が適切か？）

> Call can throw, but it is not marked with 'try' and the error is not handled

というエラーが出ました。

[code]

    extension Array {
        func mapNotNull<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult) rethrows -> [ElementOfResult] {
            return self.compactMap {
                $0
            }.map {
                transform($0) // ここでエラー
            }
        }
    }
    
[/code]

メソッド定義を

[code]

    func mapNotNull<ElementOfResult>(_ transform: (Element) -> ElementOfResult) -> [ElementOfResult]
    
[/code]

と変えた場合、エラーは消えるのですが、これだと `mapNotNull` に渡したクロージャが例外を起こすコードを書いた場合コンパイルエラー(`to
non-throwing function type`のようなコンパイルエラー)となるため、本来の map や compactMap
と違う挙動となるため、よくないと考えています（本来のmap や comapctMap に近づけたいです）

うまく `rethrows` させるにはどう書けばよいのでしょうか？

**追記：**  
そもそも`Element`が配列オブジェクトができたタイミングで型が決まるので、`mapNotNull` は実現できないきもしてきました...

**さらに追記**  
[OptionalType もしくは OptionalProtocol
はどういったテクニックなのでしょうか？](https://ja.stackoverflow.com/questions/56882/optionaltype-%e3%82%82%e3%81%97%e3%81%8f%e3%81%af-
optionalprotocol-%e3%81%af%e3%81%a9%e3%81%86%e3%81%84%e3%81%a3%e3%81%9f%e3%83%86%e3%82%af%e3%83%8b%e3%83%83%e3%82%af%e3%81%aa%e3%81%ae%e3%81%a7%e3%81%97%e3%82%87%e3%81%86%e3%81%8b)

に別の質問を足しました


CC BY-SA 4.0
2019-07-25T03:19:29.203
56873
2019-07-25T08:24:35.643
2019-07-25T08:24:35.643
9008
9008
question
swift kotlin exception
Call can throw, but it is not marked with 'try' and the error is not handled


<https://stackoverflow.com/a/44614084/1979953>

を参考に よくわかっていないですが... 下記でできました。

[code]

    protocol OptionalType {
        associatedtype Wrapped
        var optional: Wrapped? { get }
    }
    
    extension Optional: OptionalType {
        var optional: Wrapped? { return self }
    }
    
    extension Sequence where Iterator.Element: OptionalType {
        func removeNils() -> [Iterator.Element.Wrapped] {
            return self.compactMap { $0.optional }
        }
    
        func mapNotNil<R>(_ transform: (Iterator.Element.Wrapped) throws -> R) rethrows -> [R] {
            var temp: [R] = []
    
            for e in self {
                if let ee = e as? Iterator.Element.Wrapped {
                    let t = try transform(ee)
                    temp.append(t)
                }
            }
    
            return temp
        }
    }
    
[/code]


CC BY-SA 4.0
2019-07-25T05:50:03.757
56880
2019-07-25T08:16:32.587
2019-07-25T08:16:32.587
9008
9008
56873
answer


エラーを取るだけなら

[code]

    extension Array {
        func mapNotNull<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult) rethrows -> [ElementOfResult] {
            return try self.compactMap { // tryを付ける
                $0
            }.map {
                try transform($0) // tryをつける
            }
        }
    }
    
[/code]

としてください。

あなたの欲しいメソッドはおそらくはこうです。

[code]

    extension Array {
        func mapNotNull<T, ElementOfResult>(_ transform: (T) throws -> ElementOfResult) rethrows -> [ElementOfResult] 
            where Element == Optional<T> {
                return try compactMap { try $0.map(transform) }
        }
    }
    
[/code]


CC BY-SA 4.0
2019-07-25T08:07:53.407
56884
2019-07-25T08:07:53.407
2741
56873
answer