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
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
Error: Use of Unresolved Identifier 'Process'
Can the Conversion of a String to Data with Utf-8 Encoding Ever Fail
Implementing a Function with a Default Parameter Defined in a Protocol
Sprite Kit Physicsbody.Resting Behavior
How to Detect Absent Network Connection When Setting Firestore Document
Higher Order Function: "Cannot Invoke 'Map' with an Argument List of Type '((_) -> _)'"
Creating a Countableclosedrange<Character>
Non-Strong References Not Working in Playground
Why Does Swift Playground Shows Wrong Number of Executions
How to Make Physics Bodies Stick to Nodes Anchor Points
What Does "Get" Mean in a Protocol's Property Declaration
Declaration Is Only Valid at File Scope (Extension)
Swift: How to Delete Part of Audio
Beginner Swift Sprite Kit - Node Collision Detection Help (Skphysicscontact)