如何根据参数的属性约束函数泛型类型?

时间:2018-04-18 13:11:52

标签: ios swift generics

我有这个枚举:

Sub endofmonth()
  'This sub should be run at the end of the month and will generate a monthly     summary sheet
  Dim wrk As Workbook
  Dim sht As Worksheet
  Dim trg As Worksheet
  Dim rng As Range
  Dim colCount As Integer
  Set wrk = ActiveWorkbook
  For Each sht In wrk.Worksheets
    If sht.Name = "Month End" Then
      MsgBox "There is a worksheet called as 'Month End'." & vbCrLf & _
             "Please remove or rename this worksheet since 'Month End' would be" & _
             "the name of the result worksheet of this process.", vbOKOnly + vbExclamation, "Error"
      Exit Sub
    End If
  Next sht
  Application.ScreenUpdating = False
  Set trg = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
  trg.Name = "Month End"
  Set sht = wrk.Worksheets(1)
  colCount = sht.Cells(1, 255).End(xlToLeft).Column
  With trg.Cells(1, 1).Resize(1, colCount)
    .Value = sht.Cells(1, 1).Resize(1, colCount).Value
    .Font.Bold = True
  End With
  For Each sht In wrk.Worksheets
    If sht.Index = wrk.Worksheets.Count Then
      Exit For
    End If
    Set rng = sht.Range(sht.Cells(2, 1), sht.Cells(65536, 1).End(xlUp).Resize(, colCount))
    trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
  Next sht
  trg.Columns.AutoFit
  'This part of the code formats the Monthly Summary sheet correctly
  With ThisWorkbook.Sheets("Month End")
    .Columns(1).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "HH:MM AM/PM"
    .Columns(4).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "00"
    .Columns(10).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "00.00"
    .Columns(17).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "0.00%"
    .Columns(18).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "0.00%"
    .Columns(19).Resize(.Rows.Count - 1, 1).Offset(1, 0).NumberFormat = "0.00%"
    'This part of the code inserts a break at the end of every day on the monthly  summary sheet
    Dim rw As Long
    Dim lr As Long
    Dim cnt As Long
    lr = Range("A" & Rows.Count).End(xlUp).Row
    rw = 2
    cnt = 1
    Do
      If cnt = 10 Then
        Rows(rw).Insert Shift:=xlDown
        cnt = 1
        lr = Range("A" & Rows.Count).End(xlUp).Row
      Else
        cnt = cnt + 1
      End If
      rw = rw + 1
    Loop While rw <> lr

  End With
  Application.ScreenUpdating = True

End Sub

这个函数在一个类

enum ItemType: String {
        case image
        case movie

        var rawValue: String {
            switch self {
                case .image: return String(kUTTypeImage)
                case .movie: return String(kUTTypeMovie)
            }
        }
    }

现在我想要实现的是,如果ItemType是.image,我希望将完成推断为类型func items<T>(for type: ItemType, completion: ([T]) -> Void) where T: NSSecureCoding {} ,否则如果它是.video我希望它被推断为{{ 1}}

这在Swift中是否可行?或者根据提供的类型推断完成类型的替代方法是什么。

其他详细信息:

函数体使用NSItemProvider loadItem实例方法,其闭包返回符合NSSecureCoding的任何类型。所以,只要我能给出类似的类型,我就不关心它是什么类型。

([UIImage]) -> Void

1 个答案:

答案 0 :(得分:2)

您无法执行此操作,因为参数type运行时进行评估,而在编译时T需要推断出来。

解决方法是将其分为两种方法:

func itemsForImages(completion: ([UIImage]) -> Void) { ... }
func itemsForMovies(completion: ([URL]) -> Void) { ... }

然后确定要调用的方法:

switch itemType {
    case .image:
        itemsForImages { images in ... }
    case .movies:
        itemsForMovies { urls in ... }
}

另一个替代方法是使用([Any]) -> Void类型的闭包,并且调用者需要将参数强制转换为正确的类型,但这不是类型安全的。