/ / грешка: общият параметър "Т" не може да бъде извлечен в бързи - IOS, масиви, бързи, алгоритъм, генерични

грешка: общият параметър "Т" не може да бъде извлечен в бързи - IOS, масиви, бързи, алгоритъм, генерични

Имам функция, която прави плосък масив от вложени масив. Той работи перфектно за int масив.

let array: [Any] = [1, 2, [3]]

func makeFlatArray(_ array: [Any]) -> [Int] {
var flatArray = [Int]()
for item in array {
if let item = item as? Int {
flatArray.append(item)
} else if let item = item as? [Any] {
let result = makeFlatArray(item)
flatArray += result
}
}
return flatArray
}

Но искам да го направя генеричен и аз имам грешка, когато се опитвам.

func makeFlatArrayGeneric<T>(_ array: [Any]) -> [T] {
var flatArray = [T]()
for item in array {
if let item = item as? T {
flatArray.append(item)
} else if let item = item as? [Any] {
let result = makeFlatArrayGeneric(item)
flatArray += result
}
}
return flatArray
}

грешка:

Playground execution failed:

error: FlatNestedArraysExample.playground:22:26: error: generic parameter "T" could not be inferred
let result = makeFlatArrayGeneric(item)
^

FlatNestedArraysExample.playground:16:6: note: in call to function "makeFlatArrayGeneric"
func makeFlatArrayGeneric<T>(_ array: [Any]) -> [T] {

Отговори:

6 за отговор № 1

Трябва да кажете на компилатора вида T.

func makeFlatArrayGeneric<T>(_ array: [Any]) -> [T] {
var flatArray = [T]()
for item in array {
if let item = item as? T {
flatArray.append(item)
} else if let item = item as? [Any] {
let result: [T] = makeFlatArrayGeneric(item)
flatArray += result
}
}
return flatArray
}

let array: [Any] = [1, 2, [3], [4, [5]]]
let items: [Int] = makeFlatArrayGeneric(array) //[1, 2, 3, 4, 5]

По-функционален подход към решаването на вашия проблем.

extension Array {
func flatten() -> Array<Element> {
return self.flatMap({ element -> [Element] in
if let array = element as? Array {
return array.flatten()
} else {
return [element]
}
})
}
}

let items: [Int] = array.flatten() //[1, 2, 3, 4, 5]

0 за отговор № 2

Трябва да направите нещо, за да осъзнаете бързо това, което е T, един от начините да направите това е да зададете връщащата стойност на променлива, чийто тип е известен:

let result: [T] = makeFlatArrayGeneric(item)

Друг начин е да въведете типа като параметър:

func makeFlatArrayGeneric<T>(_ array: [Any], type: T.Type) -> [T] {
var flatArray = [T]()
for item in array {
if let item = item as? T {
flatArray.append(item)
} else if let item = item as? [Any] {
let result = makeFlatArrayGeneric(item, type: type)
flatArray += result
}
}
return flatArray
}

И го наречете така:

makeFlatArrayGeneric(yourArray, type: Int.self)