Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can a function return a custom TYPE?
#1
Question 
Hello! Former PDS 7.1 developer here, and I recently stumbled on some of my old source code files while digging through an old hard drive. That led me to qb64 and eventually here!

So I decided to take a stab at completing a little text-based map scroller that I started a few decades ago, and I'm using some of the new conventions available with QB64PE.

It brings me my first question: Can a function return a custom TYPE? If so, how?

Consider the following code:

Code: (Select All)
' Split a "label:value" string in to two parts, stored as a custom TYPE

Type config_item_type
    Label As String
    Value As String
End Type

Dim config_item As config_item_type
line$ = "title: Main Entrance"
config_item = Split_Header_line(lines$)
' Expecting config_item.Label = "title" and config_item.Value = "Main Entrance"

Function Split_Header_Line (line$)
    Dim result As config_item_type

    i% = InStr(line$, ":")
    If i% Then
        result.Label = LCase$(Left$(line$, i%))
        result.Value = LTrim$(Mid$(line$, i% + 1))
    End If
    Split_Header_Line = result
END FUNCTION 

I get the following two errors:

Expected = similar user defined type on line 10

and

User defined types in expresssions are invalid on line 21

Is this telling me that I can't use TYPEd variables as return types for functions or am I missing something more obvious?
Reply
#2
You can't use User Defined Types as the function return itself, but you can use them as a parameter and pass the value back and forth.   

An example with your code:
Code: (Select All)
' Split a "label:value" string in to two parts, stored as a custom TYPE

TYPE config_item_type
    Label AS STRING
    Value AS STRING
END TYPE

DIM config_item AS config_item_type
line$ = "title: Main Entrance"
junk = Split_Header_Line(line$, config_item)
' Expecting config_item.Label = "title" and config_item.Value = "Main Entrance"
PRINT config_item.Label, config_item.Value

Split_2 line$, config_item
PRINT config_item.Label, config_item.Value

FUNCTION Split_Header_Line (line$, result AS config_item_type)
    i% = INSTR(line$, ":")
    IF i% THEN
        result.Label = LCASE$(LEFT$(line$, i%))
        result.Value = LTRIM$(MID$(line$, i% + 1))
    END IF
END FUNCTION

SUB Split_2 (line$, result AS config_item_type)
    i% = INSTR(line$, ":")
    IF i% THEN
        result.Label = LCASE$(LEFT$(line$, i%))
        result.Value = LTRIM$(MID$(line$, i% + 1))
    END IF
END SUB

As you can see, you can pass those values via parameter; just not as a return through the function itself.  (Which might make it just easier to use a SUB, as I've included above as a demo for you, as well. )
Reply
#3
(06-12-2024, 11:16 PM)SMcNeill Wrote: You can't use User Defined Types as the function return itself, but you can use them as a parameter and pass the value back and forth.   

An example with your code:
Code: (Select All)
' Split a "label:value" string in to two parts, stored as a custom TYPE

TYPE config_item_type
    Label AS STRING
    Value AS STRING
END TYPE

DIM config_item AS config_item_type
line$ = "title: Main Entrance"
junk = Split_Header_Line(line$, config_item)
' Expecting config_item.Label = "title" and config_item.Value = "Main Entrance"
PRINT config_item.Label, config_item.Value

Split_2 line$, config_item
PRINT config_item.Label, config_item.Value

FUNCTION Split_Header_Line (line$, result AS config_item_type)
    i% = INSTR(line$, ":")
    IF i% THEN
        result.Label = LCASE$(LEFT$(line$, i%))
        result.Value = LTRIM$(MID$(line$, i% + 1))
    END IF
END FUNCTION

SUB Split_2 (line$, result AS config_item_type)
    i% = INSTR(line$, ":")
    IF i% THEN
        result.Label = LCASE$(LEFT$(line$, i%))
        result.Value = LTRIM$(MID$(line$, i% + 1))
    END IF
END SUB

As you can see, you can pass those values via parameter; just not as a return through the function itself.  (Which might make it just easier to use a SUB, as I've included above as a demo for you, as well. )
I would use the function and return i%
when returned you might want to know if the config_item was changed
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#4
(06-12-2024, 11:16 PM)SMcNeill Wrote: You can't use User Defined Types as the function return itself, but you can use them as a parameter and pass the value back and forth.   
[...]
As you can see, you can pass those values via parameter; just not as a return through the function itself.
Ah, I completely forgot about that. It's like passing a parameter by reference in other languages. Thank you!

(06-13-2024, 12:54 PM)mdijkens Wrote: I would use the function and return i%
when returned you might want to know if the config_item was changed
That is very good point! I was just going with "IF LEN(config_item.label) THEN" but I like your way better. Thank you!
Reply




Users browsing this thread: 6 Guest(s)