Swift error: Missing return in a function expected to return 'String' - swift

I'm trying to add edit some code from Apple's QuestionBot. I came up with this:
func responseToQuestion(question: String) -> String {
if question.hasPrefix("hello") {
return "Hello"
} else if question.hasPrefix("where") {
return "There"
} else if question.hasPrefix("what"){
return "I don't know"
}
}
But there's an error: Missing return in a function expected to return 'String'. What should I do, thanks?

Missing return in a function expected to return 'String'
should the function return something , because you did not set return if do not match any one question.hasPrefix()
func responseToQuestion(question: String) -> String {
if question.hasPrefix("hello") {
return "Hello"
} else if question.hasPrefix("where") {
return "There"
} else if question.hasPrefix("what"){
return "I don't know"
}
return "something"
}

Related

Missing return in global function expected to return 'String' message in a function

I know this error is a common message and has already been the subject of many posts. However, as a pure beginner who just started days ago, I can't really understand the solution on other posts, and also haven't learned what Switch means. Thefore, that solution can't be used with me. Here's my block code getting the error :
func responseTo(question: String) -> String {
let lowercasedQuestion = question.lowercased()
if lowercasedQuestion.hasPrefix("hello") {
if lowercasedQuestion.hasPrefix("Hello") {
return "Why, hello there!"
} else if lowercasedQuestion.hasPrefix("where") {
if lowercasedQuestion.hasPrefix("Where") {
return "To the North"
} else {
return "Where are the cookies?"
}
}
}
}
I tried to put the last else outside the first if since I read it could change the output and remove the error, but it didn't change anything. I tried to enter return nil on the last line, but had an error. What can I do? Any answer appreciated.
Your responseTo(String) -> String function must return a String. You must consider this case, if the parameter (question) doesn't start with "hello", the function doesn't have any String to return.
let result: String = responseTo("asd") // error
As stated in the comments, there are several ways to solve this.
If your function must return a string, then consider returning a default value at the end. The return value can be an empty string (but whatever your default value is, make sure to handle it properly).
func responseTo(question: String) -> String {
let lowercasedQuestion = question.lowercased()
if lowercasedQuestion.hasPrefix("hello") {
//
} else {
return "" // this will be the default return value
}
}
or
func responseTo(question: String) -> String {
let lowercasedQuestion = question.lowercased()
if lowercasedQuestion.hasPrefix("hello") {
//
}
return "" // this will also be the default return value
}
Another way is to return an Optional String (String?). The reason why return nil doesn't work for responseTo(String) -> String is because it must return a string. To be able to return a nil, you will have to change the declaration of your function to responseTo(String) -> String?.
func responseTo(question: String) -> String? { // the "?" after String notifies the compiler that this function can return a String or a nil
let lowercasedQuestion = question.lowercased()
if lowercasedQuestion.hasPrefix("hello") {
//
}
return nil
}
you can read more about function here and optional here

trying to add Go Back” function in WebView inside Fragment, but its showing this error

This is my code
ERROR - " Type mismatch: inferred type is Unit but Boolean was expected "
webview2.setOnKeyListener(View.OnKeyListener {
fun onKey( int: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN){
if(int == event.keyCode){
if( webview2!=null){
if (webview2.canGoBack()){
webview2.goBack()
} else{
activity?.onBackPressed()
}
}
}
}
return true;
}
})

Why ReturnType is not working in this Swift function?

I am working with Swift 5, in Xcode 10.2.1
I have this function inside of an extension of UInt8
The compiler complains in line 5, with Unexpected non-void return value in void function
The return type is properly defined, and if the line return "\(opCode)" is commented, it works fine, with the return in the last line return "\(OpCode.NOP) I am using "\(OpCode.NOP)" to avoid adding another variable to the enum, but is a regular string
The error continues if I change the line to return "", so it has nothing to do with the OpCode enum.
extension UInt8 {
func opCode() -> String {
OpCode.allCases.forEach { opCode in
if self == opCode.uint8 {
return "\(opCode)" //Unexpected non-void return value in void function
//return "" // Error persists
}
}
return "\(OpCode.NOP)"
}
}
You can't return a value inside void return type of the forEach instead try
extension UInt8 {
func opCode() -> String {
if let item = OpCode.allCases.first(where:{ self == $0.uint8 }) {
return "\(item)"
}
return "\(OpCode.NOP)"
}
}

Swift try-catch handling within a function or class

I try to become acquainted with the try&catch construct in Swift.
Sorry, i couldn't find an answer in related posts!
Is it possible to hide this into a function or class as shown here?
class Test {
enum TestError:ErrorType{
case a
case b
}
func a(s:String) throws -> String{
if s == "OK" {
return "OK"
}else{
throw TestError.a
}
}
func b(s:String) throws -> String{
if s == "OK" {
return "OK"
}else{
throw TestError.b
}
}
func doTest(str:String) -> String{
do{
let s = try a(b(str)) // <= ERROR
}catch TestError.a{
return "a failed!"
}catch TestError.b{
return "b failed!"
}
}
}
I always get
error: errors thrown from here are not handled because the enclosing
catch is not exhaustive
Is it in principle impossible and only applicable in the main program?
Or is there a way around?
The compiler needs a clause in case a different error is thrown. I like to do a global catch like this, by casting to NSError:
do {
return try a(b(str))
} catch TestError.a {
return "a failed!"
} catch TestError.b {
return "b failed!"
} catch let error as NSError {
return "\(error.description)"
}
You also have to return the String at the try.

"Missing return in a closure expected to return 'SomeType'" error in .map

I have the fallowing code:
struct AInt {
var aInt: Int
}
struct ADouble {
var aDouble: Double
static func convert(aInt: AInt) throws -> ADouble {
return ADouble(aDouble: Double(aInt.aInt))
}
}
struct B {
func doAction(aInts: [AInt]) throws -> [ADouble] {
return aInts.map { aInt in
do {
try ADouble.convert(aInt)
}
catch {
print(error)
}
}
// ^^^ error here: Missing return in a closure expected to return 'ADouble'
}
}
let aInts = [AInt(aInt: 2), AInt(aInt: 3)]
let b = B()
do {
print(try b.doAction(aInts))
}
catch {}
When i'm trying to convert [AInt] to [ADouble] in .map using function that can throw error, i get this error:
Missing return in a closure expected to return 'ADouble'.
Well, i decided to add return statement in the end of .map like this:
return aInts.map { aInt in
do {
try ADouble.convert(aInt)
}
catch {
print(error)
}
return ADouble(aDouble: 2.2)
}
Error disappear, but when i print try b.doAction(aInts) on same aInts array, i get this: [ADouble(aDouble: 2.2), ADouble(aDouble: 2.2)], i.e. it prints my ADouble(aDouble: 2.2) that i set manually. Obviously, it's not what i want, so then i try to add return before try ADouble.convert(aInt) like this:
return aInts.map { aInt in
do {
return try ADouble.convert(aInt)
}
catch {
print(error)
}
return ADouble(aDouble: 2.2)
}
And now i get right result: [ADouble(aDouble: 2.0), ADouble(aDouble: 3.0)]. But this code still doesn't work without return statement in the end of the .map. Any ideas how to get rid of it?
The map() method is declared as
#rethrows public func map<T>(#noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]
which means (if I understand it correctly) that the transform can
either return a value or throw an error (and this will be
forwarded to the caller).
This compiles and works as expected:
struct B {
func doAction(aInts: [AInt]) throws -> [ADouble] {
return try aInts.map { aInt in
return try ADouble.convert(aInt)
}
}
}
An error thrown from ADouble.convert(aInt) will be forwarded to
the caller of map() and from there to the caller of doAction().