What Is a 'Non-Nominal Type' in Swift

What is a 'non-nominal type' in Swift?

This is somewhat of a guess (edit: it's wrong, look at Brent's answer), but here goes:

Any is a protocol, not an actual type. The word "Nominal" implies naming (based on the root of the word).

So you can't extend Any because it's a protocol, not an actual type, and you can't extend (Int, Int) because that's just a tuple literal, again not an actual type that you could specify by name.


Update:

You can, of course, extend protocols. Any is not a protocol, it's (shocker) a non-nominal type which is something else. Read Brent's answer; he did a good job.

Swift 4: Non-nominal type 'T' does not support explicit initialization

This happens because the compiler doesn't know which initializer it is supposed call, because what you are doing is simply too general, as the error states.
What you are trying to achieve can be done, but the implementation depends on what you are achieve.

In short, if you want to be able to initialize a lot of different types, be it primitives or objects, you should define a new protocol, extend each type to implement this protocol as you see fit and have the T Type restricted to this protocol.

Example:

protocol HTTPHeaderProtocol {
init(_ headerProtocolString: String?)
}

class MyCustomObject: HTTPHeaderProtocol {
var myString = ""
required init(_ headerProtocolString: String?) {
self.myString = headerProtocolString ?? ""
}

}

extension String: HTTPHeaderProtocol {
init(_ headerProtocolString: String?) {
self.init(headerProtocolString)
}
}

extension Int: HTTPHeaderProtocol {
init(_ headerProtocolString: String?) {
self.init(headerProtocolString)
}
}

extension HTTPURLResponse {

func get(_ header: String) -> String? {
let keyValues = allHeaderFields.map { (String(describing: $0.key).lowercased(), String(describing: $0.value)) }

if let headerValue = keyValues.filter({ $0.0 == header.lowercased() }).first {
return headerValue.1
}
return nil
}
func getHeader<T:HTTPHeaderProtocol>(_ httpResponse: HTTPURLResponse, _ headerName: String) -> T? {
guard let element = httpResponse.get(headerName) else {
return nil
}
return T(element)
}
}

This will work, hope that helps:)

Swift generics init: Non-nominal type 'T' does not support explicit initialization

The type system doesn't know, from your list of generics <T: Cacheable, U: RealmObject>, that U is the correct type of RealmObject for T (in other words, you could be passing a Note as T, and an AppointmentObject as U). You just need to update your function signature to:

// The `where T.T == U` is the important part. Because that is defined,
// we can also remove `U: RealmObject` because it's redundant information.
func getCacheable<T: Cacheable, U>(from realmObject: U) -> T where T.T == U {
let thing = T(object: realmObject)
return thing
}

// Alternatively, you can just do:
func getCacheable<T: Cacheable>(from realmObject: T.T) -> T {
let thing = T(object: realmObject)
return thing
}

Swift 4: Non-nominal type 'T' does not support explicit initialization

Here is the error I am getting
Sample Image

Its getting confused with the type(of: and the argument type.

After changing T.Type argument name. Its working :

extension Collection {
/// Finds and returns the first element matching the specified type or nil.
func findType<T>(_ typeT: T.Type) -> Iterator.Element? {
if let index = (index { (element: Iterator.Element) in
String(describing: type(of: element)) == String(describing: typeT) }) {
return self[index]
}
return nil
}
}

Non-nominal type 'User' does not support explicit initialization

The User in your class is not the same as the User type you created. It's just a placeholder for any type. You could replace the word User in your class definition with anything e.g. T or Apple and it would still be the same definition.

The compiler knows nothing about whatinit methods User in your class has, hence the error. To make it work properly, you must constrain the type parameter. This is usually done by making it conform to a protocol e.g.

protocol JSONInitable
{
init(json: JSON)
}

struct User: JSONInitable { ... }
struct Group: JSONInitable { ... }

class LoginTask<PrincipalType: JSONInitable>
{
....

func foo()
{
let user = PrincipalType(json: response)
}
}

In the above, the LoginTask can be used with both User and Group but not any arbitrary type that doesn't conform to the protocol.

Alternatively, if the class will always use the User type, it doesn't need to be generic.

Swift 4: Non-nominal type 'T' does not support explicit initialization when converting Objective-c to Swift

PrintBlock is an alias for a closure. You can't simply create an instance like you would a class or struct. You need to assign a closure (or function) to the property.

The Swift code would be:

typealias PrintBlock = (_ printer: HLPrinter?) -> Void

class ShoppingViewController: UIViewController {
var printBlock: PrintBlock?

func getPrinter() -> HLPrinter {
return somePrinter
}

func someFunction() {
if let printBlock = printBlock {
let printer = getPrinter()
printBlock(printer)
}
}
}

The calling code would be something like:

let vc = ShoppingViewController()
vc.printBlock = { (printer) in
// do something with printer
}

Or if you have a function:

func someFunction(_ printer: HLPrinter) {
}

You can assign that:

vc.printBlock = someFunction

There's a few assumptions in here based on the partial information you have provided in your question.

non-nominal type X does not support explicit initialization

You just need to use init explicitly whenever you're initializing a generic parameter rather than a "real" type:

self.c = C.init(modelView: m)

Non-nominal type Self doesn't support explicit initialisation (protocol extension for enums)

You need to use the proper Self reference instead of self and constrain your extension to only types with the RawValue of Int.

protocol CountableEnum: RawRepresentable {
static var count: Int { get }
}

extension CountableEnum where RawValue == Int {
static var count: Int {
var max = 0
while let _ = Self(rawValue: max) { max += 1 }
return max
}
}


Related Topics



Leave a reply



Submit