Why Does 'Defined' Return a String or Nil

Why does `defined?` return a string or nil?

No, it was neither a hack nor a misuse of Ruby convention. As matz writes in ruby-talk 7986:

The '?' methods ... return either

  • (a) true or false
  • (b) non-false informative value or nil

defined? falls into (b).

Also, as commenters have pointed out, defined? is not a method. Matz expands in ruby-talk 1637:

[defined? is] a control structure. Not everything is a message send in Ruby, e.g. control structures, variables, blocks are not objects. defined? is among these things.

Why does my variable return null instead of the defined value

The reason console.log(carry) returns Nan is because you wrote: carry = parseInt(sum) / 2;
This redefines carry to Nan instead of 0 (first time you go through the while loop carry is 0, but second time it is Nan). parseInt(sum) returns null (Nan), because at another point you wrote b[i] instead of b[j].

Why can't a string be nil in Go?

The simple answer is that nil is not defined to be a valid value for type string in the language specification.

...but maybe you want a longer answer?

nil is the zero value for pointers, interfaces, channels, slices, maps and function types, and it represents an uninitialized state.

Consider the following variable declarations:

var a *SomeType
var b interface{}
var c func()

It seems natural that all these variables would have a value that represents uninitialized state. a has been declared as a pointer, but what would it point to, when we haven't yet pointed it at anything? nil is an obvious zero value for these types.

As for channels, slices and maps, their zero value is nil for the simple reason that their implementation is such that they must be explicitly initialized before they can be used. This is mostly for performance reasons, these types are all represented internally as more or less complex data structures, and initializing them is not free.

However, a string doesn't require initialization, and it seems natural that the default, zero value for a new string variable would be an empty string, "". Therefore there's simply no reason for nil to be a valid string value, and adding it to the specification would only make the language more complicated and much more cumbersome to work with.

Furthermore, what would nil of type string represent? An empty string? We already have that. An uninitialized string? There's no such thing.

How to create a function that can return nil or string value instead of the memory address?

To summarize the various comments:

You can simply return an empty string instead of a pointer.

func Convert(r io.Reader) (string, error) {
dat := "hello"
return dat, nil
}

func ConvertPath(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", err
}
defer f.Close()

return Convert(f)
}

func main() {
dat, err := ConvertPath("/tmp/dat2")
if err != nil {
panic(err)
}
fmt.Println(dat)
}

Are `return nil` and `return` interchangeable?

Nope they're not the same.

Returning nil is used when you need to return a value but that value can be optional. So in your example:

func naming(name: Int) -> String? {
switch name {
case 0: return "Neo"
case 1: return "Matrix"
default: return nil
}
}

The function is expecting a String OR a nil value to be returned, hence String?. The question mark on the end indicates that the String is optional. When you call naming(name: 2) that calls the switch statement and doesn't find a value corresponding to the number 2, so defaults to returning nil.

Putting return like in your second example just stops the rest of the function from executing. So:

function loadVideo() {
guard let video = try? avplayer else {
print("Unable to load a movie")
return
}
print("hello")
}

If the avplayer variable is nil then the guard statement will execute its else statement and print out Unable to load a movie then return from the function. This will prevent hello from being printed.

Value must be type of string, null returned

The getter getLat has the return type hint string, which means only actual string values (that also means: no null values!) as return values are accepted.

You didn't show the code where you actually work with the entity, but it basically comes down to the default value of every property in an object being null if not defined differently.

Look at this example:

$address = new Address();

// the following lines will produce an error in your example
// because your return type hint doesn't allow null values

$address->getId(); // returns null
$address->getStreet(); // returns null
$address->getLat(); // returns null

$address->setLat("4.56789");

$address->getLat(); // returns "4.56789"

Note regarding Doctrine:

If the values in the database are set correctly, you won't run into this problem after Doctrine populated the entity (e.g. via $address = $addressRepo->find(123);). It should only happen, when you create a new entity yourself and then try to use the getter methods.

Possible solutions:

1.) Allow null values as return values. Prepend your return type hints with a question mark, like this:

/**
* @return string|null
*/
public function getLat(): ?string
{
return $this->lat;
}

But if you do this, your code must be ready to handle null values from these methods!

2.) Define default values with the correct data type in your object:

/**
* @var string
*
* @ORM\Column(name="lat", type="decimal", precision=10, scale=8, nullable=false)
*/
private $lat = "";

Your code must be ready to handle empty strings as return values then! Alternativly you can also define the default values in a constructor method.

3.) Require these properties to be available by making them parameters of your constructor:

public function __constructor(string $lat, string $lng /*, add the other required properties */) {
$this->lat = $lat;
$this->lng = $lng;
// ... additional properties here ...
}

In that case you must provide the values when you create the object with new Address(/* parameters go here */);.



Related Topics



Leave a reply



Submit