Return array in function

I am new to Kotlin and find it confusing at times (never done java either). Having done the basics of Kotlin in the past couple of weeks coding simple things I now find myself learning classes. I am trying to return an array from a method in a simple class. The goal of this code is to check if a file exists and if it is readable then open it for reading and lastly print the contents of it.

I am aware that my “style” is not correct and maybe I am using the wrong array type so I will appreciate it if you could steer me in the right direction in how to write the below code differently or more efficiantly. The link to the names.txt file is here

import java.io.*
import java.util.*
import java.text.*

fun main(){
var checkFileProperties = PersonalData("names.txt");
println(checkFileProperties) // Prints -> PersonalData(nameOfFile=names.txt)
/*
//If I do the lines below I get the following error: "For-loop range must have an 'iterator()' method"
for ( resultCheckFileProperties in checkFileProperties ){
print(resultCheckFileProperties)
}
*/

}

data class PersonalData ( val nameOfFile: String ) {
    val fileDir = "C:\\Users\\Flower\\Documents\\learn\\kotlin\\resources" ; //where the txt files are stored
    val nameFile = File("${fileDir}\\${nameOfFile}")
    var dataReturnValue: MutableList<String> = ArrayList() 

    private fun checkFileExists(): MutableList<String> {
        var fileExists = nameFile.exists()
        if ( fileExists ){
            dataReturnValue.add("true")

            var fileRead = nameFile.canRead()
            if ( fileRead ) {
                dataReturnValue.add("true")
            } else {
                dataReturnValue.add("false")
            }
        } else {
            dataReturnValue.add("false")
        }
        return dataReturnValue
        }
}
Summary

Thank you

The immediate issue with the commented-out code is that you’re creating an instance of your PersonalData class and assigning it to checkFileProperties. You’re not calling its checkFileExists() method at all, which is why you’re not getting the list of strings that that would return.

There are a couple of ways to fix that, but it’s hard to say more without knowing what you’re trying to achieve overall with this; clearly it’s either a work-in-progress or a smaller part of something larger, so while there’s a lot I’d rewrite if this were a final version, none of that may apply here.

The most obvious question is what your checkFileExists() is intended to do. If you just want to check whether the file exists and is readable, then the whole function could just return a Boolean and look like this:

private fun checkFileExists() = nameFile.exists() && nameFile.canRead()

No need for any lists there at all!

(And even if you want to return multiple flags for some reason, those would be much better as booleans rather than strings. Though if you have multiple flags with different meanings, a list may not be a good structure for them.)

Similarly, there’s no apparent need for the PersonalData class in the code as posted; checkFileExists() could be a stand-alone function, either taking the filename or as an extension function on File.

But if there is a reason for PersonalData, then you’ll need to call its checkFileExists() method, e.g.:

val checkFileProperties = PersonalData("names.txt").checkFileExists()
println(checkFileProperties)

or:

val checkFileProperties = PersonalData("names.txt")
println(checkFileProperties.checkFileExists())

PS. What you’re returning isn’t an array: it’s a list. But that’s fine; in Kotlin, lists are more common, more flexible, and have better support throughout the standard library. Arrays are needed for interoperability with Java, for varargs support, and for implementing some low-level structures; but otherwise, it’s generally better to use lists.

(And to avoid confusion, ArrayList is a list, not an array. Internally, it’s implemented using an array, so has that name to distinguish it from other list implementations such as LinkedList.)

3 Likes

Thank you for taking the time to reply. A lot makes sense now. This code must just read the file and print line by line the contents of said file. The reason I am using a class is because I am under the impression that classes must be created for everything even if you just want a normal function. I am not entirely sure WHEN to use classes.

No, while this is true for programming languages like java this is not the case in kotlin. You can just create a function outside of a class and use it. The println function is one example for such a funciton.

This is something I remembered I struggled with when I first started. Knowing when to use what feature and how to design your program is something that comes with experience. An easy guideline is that you should use classes when you want to group data, that means a collection of variables that all belong together, combined with the methods that are used only on that data, eg. just based on the name of your class PersonalData I would expect it to contain maybe a name, address, age, etc. What methods to put in your classes is a bit more complicated, since it depends on your program and how you want to design it.

2 Likes

I initially struggled to understand what practical difference classes made. Here’s how my father explained it to me when I was growing up and first coding:

Imagine you set out to create a tick-tac-toe program. If you’re coding imperatively, or without objects, you might first ask “what do I do?”. You might answer something like, “I draw lines for the game board, then I set the score to zero, then I get the players first move, then I compute the opponent’s next move…”. You would likely break down the large steps into a few smaller more detailed ones. Notice how you’re focused on what you ‘do’.

Now when object-oriented programming, you instead ask “What things do I have?”. Your answer might be something like, “I have a gameboard, I have a player, I have game-tokens”. Then you would break those down into what kinds of things and behaviors those objects have.

^ Which was enough to get me starting to understand at the time. Eventually, you’ll read different ways of thinking about classes and interfaces that will help broaden out the ideas. For now, I would follow @Wasabi375 advice and focus on using classes to organize things that have high cohesion.

The rule of “high cohesion and low coupling” is IMO the best guide for those new to object-oriented coding to remember when structuring classes. Even if you aren’t sure how to organize code, learning how to seek cohesion and avoid coupling will pull you in a good direction.

We write code for humans, not computers :person_in_lotus_position:

4 Likes

I once saw a brief introduction to object-oriented design which recommended something like:

  • Write down an English description of what you want your program to do.
  • Underline all the nouns, and write classes for them.
  • Underline all the verbs, and write methods for them.

Over-simplistic, of course, but it can be a good way to start!

I guess the natural next question would be: Why structure programs this way?⠀What’s the advantage of OO design (using classes) over traditional procedural design (just using functions)?

One of the main reasons is scalability.⠀Procedural design can work really well for small systems, but it gets harder and harder to manage as things grow.⠀(Think of systems with tens or hundreds of thousands of lines of code.)

Object-oriented languages make it much easier to split code into chunks with very limited connections between them (loose coupling), which makes them easier to read, understand, think about, test, and modify safely.⠀(As @arocnies says, we should write code for humans to read, at least as much as for computers to execute!)

They also give many more opportunities for reusing code, both yours and from libraries and frameworks.

(Those benefits also apply to small programs too, of course.⠀Once you’re used to objects, it’ll feel like a natural way to think about problems.⠀Anecdote: Way back when, after spending a year using this new-fangled ‘Java’ language, I had to go back to writing C programs — and I found myself writing what were effectively objects: structs encapsulating related fields so that they could only be seen in one file, and functions that took a pointer to the struct as the first parameter and acted like its methods.⠀Very limited, of course, but by then it felt like a natural way to structure programs.)

3 Likes