web-dev-qa-db-ja.com

数値型のみのジェネリック型制約

ジェネリック型を数値型のみに制限するジェネリッククラス(Swift)の型制約を実装する方法を理解しようとしています。たとえば、Double、Intなどですが、文字列ではありません。助けてくれてありがとう。

30
nalyd88

山かっこを使用して、ジェネリッククラス(関数に同じ構文が適用されます)の型制約(クラスとプロトコルの両方を使用)を指定できます。

class Foo<T: Equatable, U: Comparable> { }

1つのタイプに複数の要件を指定するには、where句を使用します。

class Foo<T: UIViewController where T: UITableViewDataSource, T: UITextFieldDelegate> { }

ただし、総称パラメーター句でオプションの要件を指定できるようには見えないため、考えられる解決策の1つは、すべての数値型が拡張機能を介して実装するプロトコルを作成し、その要件でクラスを制約することです。

protocol Numeric { }

extension Float: Numeric {}
extension Double: Numeric {}
extension Int: Numeric {}


class NumberCruncher<C1: Numeric> {
    func echo(num: C1)-> C1 {
        return num
    }
}

NumberCruncher<Int>().echo(42)
NumberCruncher<Float>().echo(3.14)
28
Martin Gordon

Strideableは、すべての標準の数値タイプが準拠するsmallest標準プロトコルですが、準拠するタイプがいくつかあります。 http://swiftdoc.org/protocol/Strideable/hierarchy/

または、IntegerTypeおよびFloatingPointTypeを使用できます。

12
DeFrenZ

列挙型で自分自身をロールバックできます:

enum Numeric {
  case NInt(Int)
  case NUInt(UInt)
  case NFloat(Float)
  case NDouble(Double)
}

次に、コードで使用します。

func myFunc(x: Numeric) -> Numeric {
  switch x {
    case let NInt(i):
      return i + 1
    case let NUInt(u):
      return u + 1
    case let NFloat(f):
      return f + 1
    case let NDouble(d):
      return d + 1
  }
}

または、NSNumberを使用することもできます。これは、いくつかの数値型を1つのブランケット型にロールアップします。

2
Yawar

here および here について説明したように、NumericプロトコルはSwift 4の一部であるため、たとえば-オーバーロードできます+数値タプルの場合は次のとおりです。

func +<T : Numeric> (x: (T, T), y: (T, T)) -> (T, T) { 
     return (x.0 + y.0, x.1 + y.1) 
}

(1,1) + (2,3) // (3, 4) : (Int, Int)
(1.25, 1.5) + (2.5, 2.25) // (3.75, 3.75) : (Double, Double)
0
Aky